logsloth.psm1

<#
.SYNOPSIS
.EXAMPLE
#>

function logsloth {
    [CmdletBinding()]
    param
    (
        [Parameter(Mandatory = $true, ValueFromPipeline = $true, ValueFromPipelinebyPropertyName = $true)]
        [System.String]
        $LINE,

        [switch]
        [Parameter(Mandatory = $false, ValueFromPipeline = $true, ValueFromPipelinebyPropertyName = $true)]
        $TASKID_AS_SYMBOL = $false
    )

    begin {
        $_oldTime = $null
        $_stackDic = @{}
        $_mainTid = 0
        $_threadIndentDic = @{}
        
        $_funcColorDic = @{}
        $_COLOR_LIST = @("Green", "Red", "DarkGray", "DarkGreen", "DarkYellow", "Gray", "Magenta", "Cyan", "DarkCyan", "DarkRed", "Yellow")
        $_COLOR_LIST | Sort-Object { Get-Random } | Set-Variable _COLOR_LIST
        $_clrIdx = 0;

        $_taskIdSymDic = @{}
        $_TASK_SYM_LIST = "§ ☆ ★ ● ◎ ◇ ◆ ■ △ ▲ ▽ ▼ ◁ ◀ ▷ ▶ ♤ ♠ ♡ ♥ ♧ ♣ ⊙ ◈ ▣ ◐ ◑ ▒ ▤ ▥ ▨ ▧ ▦ ▩ ♨ ☏ ☎ ☜ ☞ ¶ †‡ ↕ ↗ ↙ ↖ ↘ ♭ ♩ ♪ ♬ ㉿ ㈜ ㉠ ㉡ ㉢ ㉣ ㉤ ㉥ ㉦ ㉧ ㉨ ㉩ ㉪ ㉫ ㉬ ㉭ ㉮ ㉯ ㉰ ㉱ ㉲ ㉳ ㉴ ㉵ ㉶ ㉷ ㉸ ㉹ ㉺ ㉻ ⓐ ⓑ ⓒ ⓓ ⓔ ⓕ ⓖ ⓗ ⓘ ⓙ ⓚ ⓛ ⓜ ⓝ ⓞ ⓟ ⓠ ⓡ ⓢ ⓣ ⓤ ⓥ ⓦ ⓧ ⓨ ⓩ ① ② ③ ④ ⑤ ⑥ ⑦ ⑧ ⑨ ⑩ ⑪ ⑫ ⑬ ⑭ ⑮ ㊀ ㊁ ㊂ ㊃ ㊄ ㊅ ㊆ ㊇ ㊈ ㊉ ㊊ ㊋ ㊌ ㊍ ㊎ ㊏ ㊐"
        $_TASK_SYM_LIST.split(' ', [System.StringSplitOptions]::RemoveEmptyEntries) | Sort-Object { Get-Random } | Set-Variable _TASK_SYM_LIST
        $_taskIdIdx = 0
    }

    process {
        $LINE = "$LINE "
        $curTime = $null

        if ($LINE -match "\d\d-\d\d\s\d\d:\d\d:\d\d.\d\d\d") {
            $curTime = [DateTime]::Parse("18-$($matches[0])")
        }
        elseif ($LINE -match "\d\d\d\d\d\d\d\d/\d\d:\d\d:\d\d.\d\d\d") {
            $orgTimeStr = $matches[0]
            $newTimeStr = "$($orgTimeStr.Substring(0, 4))-$($orgTimeStr.Substring(4, 2))-$($orgTimeStr.Substring(6, 2)) $($orgTimeStr.Substring(9))"
            $curTime = [DateTime]::Parse($newTimeStr)
        }
        else {
            $curTime = $_oldTime
        }

        if ($_oldTime -eq $null) {
            $_oldTime = $curTime
        }

        $period = $curTime - $_oldTime
        $_oldTime = $curTime


        $res = $LINE -match "LOGID\s:\s\d+\s\|"

        if (!$res) {
            return
        }

        $res = $matches[0] -match "\d+"
        $logId = $matches[0]

        


        $res = $LINE -match "TID\s:\s[-+]?\d+\s\|"

        if (!$res) {
            return
        }

        $res = $matches[0] -match "[-+]?\d+"
        $tid = $matches[0]
        



        $taskId = $null
        $taskSym = $null
        $res = $LINE -match "TASKID\s:\s\d+\s\|"

        if ($res) {
            $res = $matches[0] -match "\d+"
            $taskId = $matches[0]

            if ($_taskIdSymDic.ContainsKey($taskId)) {
                $taskSym = $_taskIdSymDic[$taskId]
            }
            else {
                $taskSym = $_TASK_SYM_LIST[$_taskIdIdx]
                $_taskIdIdx += 1
                $_taskIdSymDic[$taskId] = $taskSym
            }
        }




        if ($_mainTid -eq 0) {
            $_mainTid = $tid
        }

        

        $funcName = $null
        $idxBar = $LINE.LastIndexOf("|")
        $idxIn = $LINE.LastIndexOf("in")
        $log = $LINE.Substring($idxBar + 2)

        

        if ($idxIn -gt 0) {
            $funcName = $LINE.Substring($idxBar + 1, $idxIn - $idxBar - 2)
            $funcName = $funcName.Trim()
        }

        $stack = $null
        $isNewTid = $false

        if ($_stackDic.ContainsKey($tid)) {
            $stack = $_stackDic[$tid]
        }
        else {
            $stack = New-Object "System.Collections.Generic.Stack[string]"
            $_stackDic[$tid] = $stack

            if ($tid -ne $_mainTid) {
                $isNewTid = $true
            }
        }

        if ([string]::IsNullOrEmpty($funcName) -and ($stack.Count -gt 0)) {
            $funcName = $stack.Peek()
        }

        if (!$_funcColorDic.ContainsKey($funcName)) {
            $_funcColorDic[$funcName] = $_COLOR_LIST[$_clrIdx];
            $_clrIdx = ($_clrIdx + 1) % $_COLOR_LIST.Length;
        }

        if ($LINE -match "\sin\s") {
            $stack.Push($funcName)
        }

        $padCount = 0

        if ($_threadIndentDic.ContainsKey($tid)) {
            $padCount += $_threadIndentDic[$tid]
        }
        else {
            if ($tid -ne $_mainTid) {
                $padCount += $_stackDic.Count * 20;
            }

            $_threadIndentDic[$tid] = $padCount;
        }
        
        $padCount += $stack.Count * 2;

        if (($LINE -match "\sout\s") -and ($stack.Count -gt 0)) {
            $res = $stack.Pop()

            if ($stack.Count -eq 0) {
                $_stackDic.Remove($tid)
            }
        }
    
        $leftPadding = " " * $padCount;
        $beuatyLog = "[$([string]::Format("{0,6:N0}", $logId))][$([string]::Format("{0,5:N0}", $period.TotalMilliseconds))ms]$($leftPadding)";

        if ($isNewTid) {
            $beuatyLog += "TID[$tid]"
        }

        if ($taskId -ne $null) {
            if ($TASKID_AS_SYMBOL) {
                
                $beuatyLog += $taskSym * 3
            }
            else {
                $beuatyLog += "TASKID[$taskId]"
            }
        }

        $beuatyLog += " $log"

        if ($_funcColorDic.ContainsKey($funcName)) {
            Write-Host $beuatyLog -ForegroundColor $_funcColorDic[$funcName]
        }
        else {
            Write-Host $beuatyLog
        }
    }
}