2011-08-11 16 views
5

Mam skrypt Perla, który jest używany do monitorowania baz danych i próbuję zapisać go jako skrypt powłoki.Uczyń dziennik wydajnym

W perl skryptu jest funkcja, która odczytuje poprzez errorlog i filtruje się, co to jest, że sprawy i wraca z powrotem. Zapisuje również bieżącą pozycję pliku dziennika, aby następnym razem, gdy musiał odczytać dziennik, można rozpocząć od miejsca, w którym zostało, zamiast odczytywać cały dziennik ponownie. Odbywa się to za pomocą funkcji tell.

Mam pomysł, aby skorzystać z polecenia Get-Content, i zacząć czytać na ostatniej pozycji, proces każdą linię aż do końca pliku, a następnie zapisać pozycję.

Znasz sztuczki, dzięki czemu można uzyskać pozycję w pliku dziennika po przeczytaniu i uczynić rozpoczęcia odczytu w określonym miejscu.

Czy istnieje lepszy i/lub łatwiejszy sposób osiągnięcia tego?

Gisli

EDIT: To musi być zrobione przez skrypt, a nie z jakiegoś innego narzędzia.

EDIT: Więc ja dostaję gdzieś z API .NET, ale to nie dość pracuje dla mnie. znalazłem pomocne linki here i here

Oto co mam do tej pory:

function check_logs{ 
param($logs, $logpos) 
$count = 1 
$path = $logs.file 
$br = 0 
$reader = New-Object System.IO.StreamReader("$path") 
$reader.DiscardBufferedData() 
$reader.BaseStream.Seek(5270, [System.IO.SeekOrigin]::Begin) 
for(;;){ 
    $line = $reader.ReadLine() 
    if($line -ne $null){$br = $br + [System.Text.Encoding]::UTF8.GetByteCount($line)} 
    if($line -eq $null -and $count -eq 0){break} 
    if($line -eq $null){$count = 0} 
    elseif($line.Contains('Error:')){ 
     $l = $line.split(',') 
     Write-Host "$line $br" 
    } 
} 

}

nie znalazłem sposób, aby poprawnie korzystać z funkcji szukania. Czy ktoś może wskazać mi właściwy kierunek?

Jeśli uruchomić ten wyprowadza 5270 ale jeśli uruchomię to z zewnątrz linii, gdzie staram się szukać w strumieniu bazowej uzyskać:

2011-08-12 08:49:36.51 Logon  Error: 18456, Severity: 14, State: 38. 5029 
2011-08-12 08:49:37.30 Logon  Error: 18456, Severity: 14, State: 38. 5270 
2011-08-12 16:11:46.58 spid18s  Error: 1474, Severity: 16, State: 1. 7342 
2011-08-12 16:11:46.68 spid18s  Error: 17054, Severity: 16, State: 1. 7634 
2011-08-12 16:11:46.69 spid29s  Error: 1474, Severity: 16, State: 1. 7894 

Jeżeli pierwsza część jest linia odczytu z rejestru a liczba na końcu reprezentuje bajty odczytane w tym punkcie. Tak więc, jak widać, próbuję teraz użyć funkcji wyszukiwania, aby pominąć pierwszą linię błędu, ale jak już powiedziałem wcześniej, wyjście to 5270, jeśli używam funkcji wyszukiwania.

Czego mi brakuje ?????

Gisli

+0

+1 za dodanie funkcji [tell] (http://perldoc.perl.org/functions/tell.html). Nie słyszałam o tym wcześniej. Zastanawiasz się tylko, czy spodziewasz się, że przepisanie skryptu będzie trudniejsze niż instalacja Perla, czy też dotyczy to wymagań? –

+0

Odtworzenie to piekło, jeśli o to pytasz. Chodzi o to, że monitorujemy bazy danych dla innych, co w przyszłości ułatwiłoby konfigurację na nowych serwerach Windows. Powinienem też wspomnieć, że tego lata jestem stażystą, a ten projekt jest także sposobem, aby pozwolić mi nauczyć się kodu i zrozumieć, co robią skrypty. I chcieli też, żeby ktoś zaczął się uczyć powershell. Krótko mówiąc, łatwiej byłoby zainstalować perl i używać tego skryptu. – Gisli

+0

Nie jestem do końca pewien, o co prosisz w tej chwili - przejdę do kolejnej lektury, ale sprawdzę zmienne - $ l jest zwrotem podziału, ale piszesz $ line - czy miałeś na myśli? – Matt

Odpowiedz

2

będzie prawdopodobnie w stanie to zrobić z niektórych obiektów .net itp ...

Jeśli jest to bardziej norma sformatowany plik dziennika nie wyglądam dużo przeszłość logparser chociaż. To było niesamowite przed czasem i wciąż jest niesamowite!

Można go używać za pośrednictwem wiersza polecenia lub COM z PowerShell. Ma możliwość zaznaczenia, gdzie znajdował się w pliku i pobrania z niego (zapisuje informacje w pliku LPC).

Może ktoś wymyślić dobry sposób na zrobienie tego, ale jeśli nie można też spojrzeć na włączeniu do zapisywania informacji o błędzie do podglądu zdarzeń. Możesz zapisać ostatni identyfikator lub ostatnio przeszukiwany podgląd zdarzeń i sprawdzić za każdym razem.

Mam nadzieję, że jest coś lepszego ...

EDIT:

Jeśli plik jest znakami tabulacji można użyć polecenia import-CSV i zapisać ostatni numer (to, że albo należy liczyć lub count-1, jeśli nagłówek jest zawarte w liczbie). Za pomocą ostatniego numeru możesz przeskoczyć do ostatniego punktu w pliku: albo możesz bezpośrednio wysłać zapytanie do bazy danych używając sp_readerrorlog; ostatni raz, jak ostatni licznik powyżej.

+0

Dzięki. Jeśli dobrze cię rozumiem, logparser to narzędzie, które powinienem pobrać i zainstalować. Powód, dla którego skrypt jest przepisywany w powershell, nie wymaga instalowania perla na nowych serwerach Windows, które monitorujemy. Mimo że jest to dobre narzędzie, możemy równie dobrze zainstalować perl na maszynie i pominąć przepisanie. I tak dziękuję – Gisli

+0

tak, to jest ... w jakim formacie jest twój plik dziennika? – Matt

+0

To jest błąd, który tworzy serwer MSSQL. Jest to zwykły plik tekstowy bez rozszerzenia (typ pliku "plik") – Gisli

0

Są dwie opcje, które proponuję, jeśli naprawdę chcesz używać PowerShell.

  1. Użyj interfejsów API pliku .NET.

  2. Przeczytaj całą zawartość dziennika, a następnie wyczyść go. Przechowuj przeanalizowaną zawartość w bazie danych.

+0

dzięki za napiwek. Przyjrzę się temu jutro – Gisli

1

Jeśli Twoim celem jest odczytanie tylko pliku z ostatniego wiersza przeczytanego w poprzednim badaniu. Prosimy o zignorowanie tej odpowiedzi. Jednak jeśli próbujesz uzyskać jakiekolwiek błędy od czasu ostatniego sprawdzenia, może to pomóc.


[System.Reflection.Assembly]::LoadWithPartialName('Microsoft.SqlServer.SMO') | Out-Null 
$server = 'ServerName' 
$chkDate = Get-Date -Date '8/16/2011 15:00' # time of last check 
$srvObj = New-Object -TypeName Microsoft.SqlServer.Management.Smo.Server -argumentList $srv 
$srvObj.ReadErrorLog(0) | foreach { if ($_.LogDate -notlike '' ` 
    -and $_.LogDate -ge $chkDate ` 
    -and $_.Text -like 'Error: *') {$_}} |ft -AutoSize 

Jeśli pick-up ostatni czas pracy z pliku, lub po prostu wiem, że uruchomienie tego co godzinę lub cokolwiek, można dostosować $ chkDate pokazać tylko błędy Odtąd do końca pliku.

(uważaj na tych back-kleszcze (`) na końcu (0) linii $ srvObj.ReadErrorLog i następnej linii. Nie zawsze wyjdzie na mnie w HTML)

+0

Dzięki za odpowiedź. Celem jest tylko odczytanie pliku.Ale czy masz link, dzięki któremu mogę przeczytać nieco więcej o funkcjach, z których korzystasz. Podobnie jak ReadErrorLog, LogDate, Text. Obawiam się, że twój kod jest trochę skomplikowany dla mnie w tym momencie, ale chciałbym to zrozumieć. – Gisli

+0

Możesz uzyskać coś z tego artykułu na Hej, Skrypciarz http://blogs.technet.com/b/heyscriptingguy/archive/2011/05/31/use-powershell-to-get-the-sql-server- error-log.aspx Wersja SMO znajduje się prawie u dołu strony. Istnieje również łącze do klasy Server z Microsoft.SQLServer.SMO .NET Framework na MSDN. – Bruce