在 PowerShell 控制台中为本机命令行应用程序的输出日志着色

Colorize output logs of a native command-line app in the PowerShell console

我正在使用 kubectl 从 pods 打印日志。 (我今天开始使用 kubectl 和 powershell 的冒险)

我们的日志总是以:

开头
[12:00:49 INF] ...
or
[12:00:49 WRN] ...
or
[12:00:49 ERR] ...

我的目标是根据日志级别查看这些行的颜色。

我假设我需要添加某种脚本到 $profile 分析 kubectl 的输出并逐行着色。

请注意,在 $profile 文件中,我已经有了 kubectl 自动完成脚本。

是否可以做,如果可以,请指导我如何做。

这可能会帮助您入门,它仅适用于 matches the pattern. You can add more options to each Key Value, such as BackgroundColor etc. This technique uses splatting 确定线条颜色的那些线条。

$test = @"
[12:00:49 INF] hello
[12:00:49 WRN] world
[12:00:49 ERR] 123
[12:00:49 INF] 123
[12:00:49 WRN] world
[12:00:49 ERR] hello
"@ -split '\r?\n'

$map = @{
    ERR = @{ ForegroundColor = 'Red' }
    WRN = @{ ForegroundColor = 'Yellow' }
    INF = @{ ForegroundColor = 'Green' }
}
[regex] $re = '^\[[\d:]+\s(' + ($map.Keys -join '|') + ')\]'

foreach($line in $test) {
    # get the key we need to use for this line with regex
    # and assign it to `$key`
    if($key = $re.Match($line).Groups[1].Value) {
        # if the line matched the pattern, get inner hashtable
        $thisline = $map[$key]
        # add this line to the inner hahstable
        $thisline['Object'] = $line
        # use splatting
        Write-Host @thisline
        # and go to next line
        continue
    }
    # if the line didn't match the pattern, use default `Write-Host` values 
    Write-Host $line
}

作为 的补充,您可以将以下内容放入 $Profile 文件中,以 自动 kubectl 的输出着色:

$KubectlStyle = @{ 
    INF = $PSStyle.Formatting.FormatAccent
    WRN = $PSStyle.Formatting.Warning
    ERR = $PSStyle.Formatting.Error 
}

$KubectlLogLevels = $KubectlStyle.Keys -join '|'
$KubectlLogPattern = "^\[.+($KubectlLogLevels)\]" 
# Uncomment to colorize the whole line:
# $KubectlLogPattern = "^\[.+($KubectlLogLevels)\].*" 

function kubectl { 
    $command = Get-Command kubectl -CommandType Application 
    & $command $args 2>&1 | ForEach-Object {
        $_ -replace $KubectlLogPattern, { 
            # produce the substitution value
            $fullMatch = $_.Groups[0].Value
            $logLevel  = $_.Groups[1].Value
            $KubectlStyle[$logLevel] + $fullMatch + $PSStyle.Reset 
        }
    }
}

输出:

着色代码需要 PS 7+,但覆盖(本机)命令的基本原理也可以应用于 PS 5.1:

  • 定义一个与原始命令同名的函数。
  • 在函数体中,使用Get-Command获取原始命令。通过传递 -CommandType Application,PowerShell 仅在 PATH 环境变量定义的路径中搜索给定名称的本机命令。因此,请确保将 kubectl 的完整目录路径添加到 PATH 变量中。
  • 使用调用运算符 & 调用原始命令,通过自动 $args 变量转发函数的参数。
  • 使用重定向运算符 2>&1 合并 stdout 和 stderr 流,这样两者都可以由 ForEach-Object 处理。
  • 现在PS7+具体代码:
    • $KubectlStyle 变量是一个 Hashtable,它将每个日志级别映射到预定义的 PowerShell 格式代码之一。在控制台中输入 $PSStyle 以查看还有哪些其他值可用。您甚至可以像这样指定 RGB 值:$PSStyle.Foreground.FromRgb(255,127,255).
    • 使用 -replace 运算符,我们定义了一个正则表达式来匹配日志行的 [...] 子字符串和一个脚本块来动态定义替换值。
    • 在脚本块中,$_ 是当前匹配项。 $_.Groups[1].Value 是“INF”、“WRN”或“ERR”,而 $_.Groups[0].Value 是完全匹配的值(整个 [...] 子字符串)。
    • 为了生成替换值,我们从 $KubectlStyle 哈希表中查找样式代码,继续添加完整匹配并添加 $PSStyle.Reset 以将样式重置为默认值。