繁体   English   中英

如何在活动运行日志的多个文本文件中搜索字符串

[英]How to search for a string in multiple text files in an active running log

我正在尝试在多个文本文件中搜索字符串以触发事件。 程序正在主动添加日志文件。 以下脚本成功实现了该目标,但一次仅适用于一个文本文件:

$PSDefaultParameterValues = @{"Get-Date:format"="yyyy-MM-dd HH:mm:ss"}

Get-Content -path "C:\Log 0.txt" -Tail 1 -Wait | ForEach-Object { If ($_ -match 'keyword') {  

Write-Host "Down : $_" -ForegroundColor Green

Add-Content "C:\log.txt" "$(get-date) down"

不幸的是,这意味着我必须运行此脚本的 3 个实例来搜索 3 个日志文件(C:\log 0.txt、C:\log 1.txt 和 C:'log 2.txt)。

我想要做的是运行一个 powershell 脚本来在所有三个文本文件而不是三个文本文件中搜索该字符串。

我尝试在路径中使用通配符 ("C:\log*.txt)

我还尝试添加一个 foreach 循环:

$PSDefaultParameterValues = @{"Get-Date:format"="yyyy-MM-dd HH:mm:ss"}

$LogGroup = ('C:\log 0.txt', 'C:\Log 1.txt', 'C:\Log 2.txt')


ForEach ($log in $LogGroup) {


Get-Content $log -Tail 1 -Wait | ForEach-Object { If ($_ -match 'keyword') {  

Write-Host "Down: $_" -ForegroundColor Green

Add-Content -path "C:\log.txt" "$(get-date) down"
Add-Content -path "C:\log.txt" "$(get-date) down"

}

       
        }
       }

这让我没有错误,但它也没有工作。

我看到其他人使用 Get-ChildItem 而不是 Get-Content 但由于这适用于一个文件......它不应该适用于多个文件吗? 我认为这是我缺乏脚本能力。 任何帮助,将不胜感激。 谢谢。

这就是您可以将已有的相同逻辑应用于一个文件但同时用于多个日志的方式,其概念是生成与$LogGroup数组中的日志路径一样多的PowerShell 实例 每个实例都被分配并将监视1 个日志路径,当关键字匹配时,它将附加到主日志文件。

这些实例被分配了相同的RunspacePool ,这有助于我们使用SemaphoreSlim实例初始化所有实例,这有助于我们确保线程安全(一次只有1 个线程可以写入主日志)。

using namespace System.Management.Automation.Runspaces
using namespace System.Threading

# get the log files here
$LogGroup = ('C:\log 0.txt', 'C:\Log 1.txt', 'C:\Log 2.txt')
# this help us write to the main log file in a thread safe manner
$lock     = [SemaphoreSlim]::new(1, 1)

# define the logic used for each thread, this is very similar to the
# initial script except for the use of the SemaphoreSlim
$action = {
    param($path)

    $PSDefaultParameterValues = @{ "Get-Date:format" = "yyyy-MM-dd HH:mm:ss" }
    Get-Content $path -Tail 1 -Wait | ForEach-Object {
        if($_ -match 'down') {
            # can I write to this file?
            $lock.Wait()
            try {
                Write-Host "Down: $_ - $path" -ForegroundColor Green
                Add-Content "path\to\mainLog.txt" -Value "$(Get-Date) Down: $_ - $path"
            }
            finally {
                # release the lock so other threads can write to the file
                $null = $lock.Release()
            }
        }
    }
}

try {
    $iss = [initialsessionstate]::CreateDefault2()
    $iss.Variables.Add([SessionStateVariableEntry]::new('lock', $lock, $null))
    $rspool = [runspacefactory]::CreateRunspacePool(1, $LogGroup.Count, $iss, $Host)
    $rspool.ApartmentState = [ApartmentState]::STA
    $rspool.ThreadOptions  = [PSThreadOptions]::UseNewThread
    $rspool.Open()

    $res = foreach($path in $LogGroup) {
        $ps = [powershell]::Create($iss).AddScript($action).AddArgument($path)
        $ps.RunspacePool = $rspool
        @{
            Instance    = $ps
            AsyncResult = $ps.BeginInvoke()
        }
    }

    # block the main thread
    do {
        $id = [WaitHandle]::WaitAny($res.AsyncResult.AsyncWaitHandle, 200)
    }
    while($id -eq [WaitHandle]::WaitTimeout)
}
finally {
    # clean all the runspaces
    $res.Instance.ForEach('Dispose')
    $rspool.ForEach('Dispose')
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM