[Logs] 日志功能 彩色命令行工具

Posted _xk

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[Logs] 日志功能 彩色命令行工具相关的知识,希望对你有一定的参考价值。

先记录后优化

使用命令行查看日志的时候,如果想要带有彩色的话,简单脚本如下。

(Version 1) 下面这个只能匹配单行

colorize.sh

#!/bin/bash
# 下面的 ERROR 等是匹配到的,区分大小写,这里的例子是 springboot 的日志
# Example:
# 2021-07-14 14:34:19.222 DEBUG 5960 --- [http-nio-8089-exec-3] c.y.c.b.m.P.selectList                   : <==      Total: 8
awk \'
function color(c,s) {
        printf("\\033[%dm%s\\033[0m\\n",30+c,s)
}
/ERROR/ {color(1,$0);next}
/SUCCESS/ {color(2,$0);next}
/WARN/ {color(3,$0);next}
/INFO/ {color(7,$0);next}
/DEBUG/ {color(6,$0);next}
{print}
\' $1
(Version 2) 匹配多行
#!/bin/bash
# 匹配ERROR 放到最后,就可以了
awk \'
function color(c,s) {
   printf("\\033[%dm%s\\033[0m\\n",30+c,s)
}
/SUCCESS/ {color(2,$0);next}
/WARN/ {color(3,$0);next}
/INFO/ {color(7,$0);next}
/DEBUG/ {color(6,$0);next}
/ERROR/,/INFO|DEBUG|WARN|SUCCESS/ {color(1,$0);next}
{print}
\' $1
(Version 3) 匹配多行
#!/bin/bash
awk \'
function color(c,s) {
        printf("\\033[%dm%s\\033[0m\\n",30+c,s)
}
/ERROR/,/INFO|DEBUG|WARN|SUCCESS/ { if ($0 !~ /INFO|DEBUG|WARN|SUCCESS/) color(1,$0);next}
/SUCCESS/ {color(2,$0);next}
/WARN/ {color(3,$0);next}
/INFO/ {color(7,$0);next}
/DEBUG/ {color(6,$0);next}
{print}
\' $1

(Powershell版本 Version1) 依赖 GunWin32 中的 awk
awk \'
function color (f,c) 
{
    f=f+30;
    # 只能用 033 不能用 e 代替
    message = \\"\\033[\\" f \\"m\\" c \\"\\033[0m\\";
    print message;
}
/ERROR/,/INFO|DEBUG|WARN|SUCCESS/ { if ($0 !~ /INFO|DEBUG|WARN|SUCCESS/) color(1,$0);next}
/SUCCESS/ { color(2,$0);next}
/WARN/ { color(3,$0);next}
/INFO/ { color(7,$0);next}
/DEBUG/ { color(6,$0);next}
{print}\' $args[0];

# Example:
$ colorize .\\logs\\spring.log

配置:

Import-Module posh-git
Import-Module oh-my-posh
# -Theme
Set-PoshPrompt powerlevel10k_rainbow

Set-Alias awk "I:\\commandLineTools\\linux\\GnuWin32\\bin\\awk.exe"
Set-Alias sed "I:\\commandLineTools\\linux\\GnuWin32\\bin\\sed.exe"
Set-Alias colorize "I:\\commandLineTools\\windows\\colorize.ps1"

(Powershell版本 Version2) 依赖 GunWin32 中的 awk
Function colorize {
    [cmdletbinding()]
    Param(
        $arg0,
        [parameter(ValueFromPipeline=$True)]
        [string[]] $InputValue
    )

    Begin {
        $txt = @();
        $isPipLine = $False;
    }

    Process {
         $value = If ($InputValue) { $InputValue } Else { $arg0 }
         If (($null -ne $InputValue) -and ($arg0 -eq $null)) {
             $isPipLine = $True;
             $txt+=$InputValue
         } Else {
             awk \'
                function color (f,c) 
                {
                    f=f+30;
                    # 只能用 033 不能用 e 代替
                    message = \\"\\033[\\" f \\"m\\" c \\"\\033[0m\\";
                    print message;
                }
                /ERROR/,/INFO|DEBUG|WARN|SUCCESS/ { if ($0 !~ /INFO|DEBUG|WARN|SUCCESS/) color(1,$0);next}
                /SUCCESS/ { color(2,$0);next}
                /WARN/,/INFO|DEBUG|ERROR|SUCCESS/ { if ($0 !~ /INFO|DEBUG|ERROR|SUCCESS/) color(3,$0);next}
                /INFO/ { color(7,$0);next}
                /DEBUG/ { color(6,$0);next}
                {print}\' $value;
         }
    }

    End {
        If ($isPipLine) {
            $txt+=$InputValue;
            $txt -Join [Environment]::NewLine | awk \'
                    function color (f,c) 
                    {
                        f=f+30;
                        # 只能用 033 不能用 e 代替
                        message = \\"\\033[\\" f \\"m\\" c \\"\\033[0m\\";
                        print message;
                    }
                    /ERROR/,/INFO|DEBUG|WARN|SUCCESS/ { if ($0 !~ /INFO|DEBUG|WARN|SUCCESS/) color(1,$0);next}
                    /SUCCESS/ { color(2,$0);next}
                    /WARN/,/INFO|DEBUG|ERROR|SUCCESS/ { if ($0 !~ /INFO|DEBUG|ERROR|SUCCESS/) color(3,$0);next}
                    /INFO/ { color(7,$0);next}
                    /DEBUG/ { color(6,$0);next}
                    {print}\';
            # echo "通过管道符"

        } Else {
            # echo "直接调用文件"
        }
    }
}

# Example:
$ sed -n \'/2021-07-16 23:31:34/,$p\' .\\logs\\spring.log | colorize
# OR
$ colorize .\\logs\\spring.log
(Powershell版本 Version3) color256
Function colorize {
    [cmdletbinding()]
    Param(
        $arg0,
        [parameter(ValueFromPipeline=$True)]
        [string[]] $InputValue
    )

    Begin {
        $txt = @();
        $isPipLine = $False;

        $script = \'
                function color (f,c) 
                {
                    f=f+30;
                    # 只能用 033 不能用 e 代替
                    message = \\"\\033[\\" f \\"m\\" c \\"\\033[0m\\";
                    print message;
                }
                function color256 (f,c) 
                {
                    # 只能用 033 不能用 e 代替
                    message = \\"\\033[38;5;\\" f \\"m\\" c \\"\\033[0m\\";
                    print message;
                }
                /ERROR/,/INFO|DEBUG|WARN|SUCCESS/ { if ($0 !~ /INFO|DEBUG|WARN|SUCCESS/) color(1,$0);next}
                /SUCCESS/ { color(2,$0);next}
                /WARN/,/INFO|DEBUG|ERROR|SUCCESS/ { if ($0 !~ /INFO|DEBUG|ERROR|SUCCESS/) color(3,$0);next}
                /INFO/ { color256(8,$0);next}
                /DEBUG/ { color(6,$0);next}
                {print}\';
    }

    Process {
         $value = If ($InputValue) { $InputValue } Else { $arg0 }
         If (($null -ne $InputValue) -and ($arg0 -eq $null)) {
             $isPipLine = $True;
             $txt+=$InputValue
         } Else {
             awk $script $value;
         }
    }

    End {
        If ($isPipLine) {
            $txt -Join [Environment]::NewLine | awk $script;
            # echo "通过管道符"

        } Else {
            # echo "直接调用文件"
        }
    }
}
(Powershell版本 Version4) color256 and pipeline
Function colorize {
    [cmdletbinding()]
    Param(
        $arg0,
        [parameter(ValueFromPipeline=$True)]
        [string[]] $InputValue,
        [Switch] $IsPipeline
    )
    # TODO: 处理管道符接受
    # $arg0
    # $InputValue

    Begin {
        $txt = @();
        $isPipLineNotByProcess = $False;

        $script = \'
                function color (f,c) 
                {
                    f=f+30;
                    # 只能用 033 不能用 e 代替
                    message = \\"\\033[\\" f \\"m\\" c \\"\\033[0m\\";
                    print message;
                }
                function color256 (f,c) 
                {
                    # 只能用 033 不能用 e 代替
                    message = \\"\\033[38;5;\\" f \\"m\\" c \\"\\033[0m\\";
                    print message;
                }
                /ERROR/,/INFO|DEBUG|WARN|SUCCESS/ { colorValue=1; if ($0 !~ /INFO|DEBUG|WARN|SUCCESS/) color(1,$0);next}
                /SUCCESS/ { colorValue=2; color(2,$0);next}
                /WARN/,/INFO|DEBUG|ERROR|SUCCESS/ { colorValue=3; if ($0 !~ /INFO|DEBUG|ERROR|SUCCESS/) color(3,$0);next}
                /INFO/ { colorValue=8; color256(8,$0);next}
                /DEBUG/ { colorValue=6; color(6,$0);next}
                {print}\';

        $colorValue="6";

        $script2 = \'
                function color256 (f,c) 
                {
                    # 只能用 033 不能用 e 代替
                    message = \\"\\033[38;5;\\" f \\"m\\" c \\"\\033[0m\\";
                    print message;
                }
                /ERROR/,/INFO|DEBUG|WARN|SUCCESS/ { colorValue=1; if ($0 !~ /INFO|DEBUG|WARN|SUCCESS/) color256(1,$0);next}
                /SUCCESS/ { colorValue=10; color256(10,$0);next}
                /WARN/,/INFO|DEBUG|ERROR|SUCCESS/ { colorValue=3; if ($0 !~ /INFO|DEBUG|ERROR|SUCCESS/) color256(3,$0);next}
                /INFO/ { colorValue=8; color256(8,$0);next}
                /DEBUG/ { colorValue=6; color256(6,$0);next}
                {color256(colorValue, $0)}\';

        $dynamicColorValue=\'{ 
                switch ($0) {
                    case /ERROR/: print 1; break;
                    case /SUCCESS/: print 10; break;
                    case /WARN/: print 3; break;
                    case /INFO/:; print 8; break;
                    case /DEBUG/:; print 6; break;
                    default: if (colorValue > 0) { print colorValue } else { print 15 }; break;
                } 
            }\';
    }

    # Process 已经是持续监听了
    Process {
         $value = If ($InputValue) { $InputValue } Else { $arg0 }
         If (($null -ne $InputValue) -and ($arg0 -eq $null) -and (!$IsPipeline)) {
             $isPipLineNotByProcess = $True;
             $txt+=$InputValue;
         } Elseif ($IsPipeline) { # 必须带有 -IsPipeline
             $colorValue=($value | awk -v colorValue=$colorValue $dynamicColorValue);
             $value | awk -v colorValue=$colorValue $script2;
         } Else {
             awk $script $value;
         }
    }

    End {
        If ($isPipLineNotByProcess) {
            $txt+=$InputValue;
            $txt -Join [Environment]::NewLine | awk $script;
            # echo "通过管道符"

        } Else {
            # echo "直接调用文件"
        }
    }
}

Function color256() {
    foreach($fgbg in 38,48)# Foreground / Background
    {
        foreach($color in 0..255) # Colors
        {
            # Display the color
            Write-Host -NoNewline ("`e[${fgbg};5;${color}m  {0,3}  `e[0m" -f $color);
            # Display 6 colors per lines
            if( (($color + 1) % 8) -eq 0 ) {
                # 使用 [Environment]::NewLine, 会导致中间空出一行
                echo `r;
            }
        } 
        echo `r;
    }
}

这个 powershell version 2, 3 和 4 版本需要配置 $profile 对应的 Microsoft.PowerShell_profile.ps1

Import-Module posh-git
Import-Module oh-my-posh
# -Theme
Set-PoshPrompt powerlevel10k_rainbow

Set-Alias awk "I:\\commandLineTools\\linux\\GnuWin32\\bin\\awk.exe"
Set-Alias sed "I:\\commandLineTools\\linux\\GnuWin32\\bin\\sed.exe"
Import-Module "I:\\commandLineTools\\windows\\colorize.ps1"

$awkLogFormatScript=\'
function color (f,c) 
{
    f=f+30;
    # 只能用 033 不能用 e 代替
    message = \\"\\033[\\" f \\"m\\" c \\"\\033[0m\\";
    print message;
}
function color256 (f,c) 
{
    # 只能用 033 不能用 e 代替
    message = \\"\\033[38;5;\\" f \\"m\\" c \\"\\033[0m\\";
    print message;
}
/ERROR/,/INFO|DEBUG|WARN|SUCCESS/ { if ($0 !~ /INFO|DEBUG|WARN|SUCCESS/) color(1,$0);next}
/SUCCESS/ { color(2,$0);next}
/WARN/,/INFO|DEBUG|ERROR|SUCCESS/ { if ($0 !~ /INFO|DEBUG|ERROR|SUCCESS/) color(3,$0);next}
/INFO/ { color256(8,$0);next}
/DEBUG/ { color(6,$0);next}
{print}\';

Java 命令运行 jar 重定向处理 output

Example1:

$ java -jar .\\target\\demo.jar --spring.profiles.active=local | awk $awkLogFormatScript

Microsoft.PowerShell_profile.ps1

$PSDefaultParameterValues = @{\'Out-File:encoding\'=\'utf8\'}
Import-Module posh-git
Import-Module oh-my-posh
Set-PoshPrompt  powerlevel10k_rainbow

Set-Alias docker-tags -Value "E:\\docker-tag\\docker-tags.ps1"
Set-Alias awk "I:\\commandLineTools\\linux\\GnuWin32\\bin\\awk.exe"
Set-Alias sed "I:\\commandLineTools\\linux\\GnuWin32\\bin\\sed"
Import-Module "I:\\commandLineTools\\windows\\colorize.ps1"
$awkLogFormatScript=\'
function color (f,c) 
{
    f=f+30;
    # 只能用 033 不能用 e 代替
    message = \\"\\033[\\" f \\"m\\" c \\"\\033[0m\\";
    print message;
}
function color256 (f,c) 
{
    # 只能用 033 不能用 e 代替
    message = \\"\\033[38;5;\\" f \\"m\\" c \\"\\033[0m\\";
    print message;
}
/ERROR/,/INFO|DEBUG|WARN|SUCCESS/ { if ($0 !~ /INFO|DEBUG|WARN|SUCCESS/) color(1,$0);next}
/SUCCESS/ { color(2,$0);next}
/WARN/,/INFO|DEBUG|ERROR|SUCCESS/ { if ($0 !~ /INFO|DEBUG|ERROR|SUCCESS/) color(3,$0);next}
/INFO/ { color256(8,$0);next}
/DEBUG/ { color(6,$0);next}
{print}\';

Example:

# test.log
$ cat > ./test.log <<EOF
AA SDF
BB DERT
CC DERA
DD TYU
EE ASDF
FF DERT
EOF
awk \'
/^BB/,/FF/{
print
getline
}\' ./test.log
# Output:
#   BB DERT
#   DD TYU
#   FF DERT
awk \'
/BB/,/FF/{
print
}\' ./test.log
# Output:
#   BB DERT
#   CC DERA
#   DD TYU
#   EE ASDF
#   FF DERT
awk \'
/BB/,/FF/{
  if ($0 !~ /FF/) print $0
}\' ./test.log
# Output:
#   BB DERT
#   CC DERA
#   DD TYU
#   EE ASDF
# 使用例子:
$ sed -n \'/2021-07-14 14/,$p\' ./logs/spring.log | colorize
$ sed -n \'/2021-07-14 14/,$p\' ./logs/spring.log | head -n 200 | colorize
$ zcat ./logs/spring.log.2021-07-10.0.gz | sed -n \'/2021-07-10 14:45/,$p\' | head -n 200 | colorize
$ java -jar ./demo.jar --spring.profiles.active=local | colorize

附件:
GunWin32附件

如果想要更多的色彩,下面的文章有将到,后面有空再写 256 color 的脚本。

Refs:

  • Shell - Customize the color of each line of a log file based on a pattern
  • Terminal Control Sequences 终端控制转义序列
  • Enable 256 Color Terminal in Ubuntu
  • Features/256 Color Terminals
  • 在 NodeJS 终端输出有简单样式的文本内容
  • awk print matching line and line before the matched
  • Print current,next,previous line using awk,sed - BASH
  • 【Linux】控制 Bash 输出的格式与颜色

以上是关于[Logs] 日志功能 彩色命令行工具的主要内容,如果未能解决你的问题,请参考以下文章

linux服务器的网站日志怎么查看?

常用命令

Linux服务器查看日志的几种方法

Docker logs 命令参数&使用场景

python 彩色日志配置

sql [SQL查询片段]用于在命令行或通过R和其他工具使用SQL的快速代码段#tags:sql,R,text processing,命令li