tail w PowerShell

Ostatnio pisaliśmy o tym jak zrobić linuksowego watch w Widnowsie (bez aplikacji „3rd party”), i od razu na myśl przyszło mi pokazać Wam, że PowerShellu bardzo łatwo można też obserwować logi np. aplikacyjne w czasie rzeczywistym. tail -f pełną parą!

Obserwowanie pliku w oczekiwaniu na zdarzenie jest lepsze niż każdorazowe odświeżanie Podglądu zdarzeń prawda? Jeśli się nie zgadzacie, to być może nie jest to dla Was tak uciążliwe jak dla mnie. Albo otwieranie za każdym razem w notatniku jakiegoś pliku w poszukiwaniu nowych wpisów. Jeśli szukacie co jest na pewno w pliku, to pewnie takie metody w zupełności wystarczą, ale co jeśli nie jesteście pewni czy wpis do pliku już nastał, czy dopiero nastąpi?

Jeśli chcemy monitorować plik w Linuksie to wystarczy wpisać w konsoli tail -f nazwapliku i podglądacie sobie zmiany w konsoli. A co możemy zrobić na Windowsie? W tytułowym PowerShellu taka operacja dość prosta:

Get-Content nazwapliku.txt -Wait

Jeśli log jest długi – konsola zostanie zalana całą zawartością, dlatego lepiej okroić plik do ostatnich kilkunastu wierszy:

Get-Content nazwapliku.txt -Tail liczba_wierszy -Wait

A jeśli ktoś chce ładniejszy, tabelaryczny widok to polecam taką składnię:

Get-Content nazwapliku.txt -Tail liczba_wierszy -Wait | Out-GridView

Czy da się też schludnie monitorować kilka plików naraz? Da się 😊 Ale to już nie będzie one-liner, a mały workflow:

Workflow Monitor-File{
Param(
[string[]]$Path
)
foreach -parallel ($file in $path) {
    „Obserowany plik: $file”
    Get-Content -path $file -tail 1 -wait
}
}

I teraz w konsoli wywołujemy polecenie:

Monitor-File log1.txt,log2.txt

Tak wyglądają monitrowane pliki, pod okienkiem „Running” jest informacja o kolejnym pliku i pierwszych wierszach

Ponieważ okno o postępie może zasłonić część tekstu, polecam przed uruchomieniem trzasnąć kilka enterów.
A co jeśli chcemy obserwować logi systemowe? Tym razem do pisania jest nieco więcej, poniżej moja propozycja:

Get-WinEvent -LogName $logname |Tee-Object -Variable index1;
$index1 = ($index1 | Sort-Object -Property RecordID -Descending| Select-Object -First 1).RecordId;for(;;) {
Start-Sleep -Seconds 1
$index2 = (Get-WinEvent -LogName $logname -MaxEvents 1).RecordId
if($index2 -gt $index1)
{
Get-WinEvent -LogName $logname -MaxEvents ($index2 – $index1) | sort RecordId
}
$index1 = $index2
}

Do zmiennej logname wystarczy przypisać log, do którego chcecie się odwołać i to wystarczy.

Sporo nowych konstrukcji zostało użytych w tym wpisie, tym bardziej zachęcam do eksperymentowania i dyskusji 😊

Marcin Kuchczyński

Wielki fan automatyzowania wszystkiego, co trzeba wykonać więcej niż 2 razy. Cierpliwie rozwijający się w kierunku rozwiązań chmurowych i raczkujący w sferze sztucznej inteligencji. W IT od 2016 roku.

Leave a Reply