2011-08-11 31 views
5

Tôi có một tập lệnh perl được sử dụng để giám sát cơ sở dữ liệu và tôi đang cố viết nó dưới dạng tập lệnh PowerShell.Tạo nhật ký đọc hiệu quả

Trong tập lệnh perl có chức năng đọc thông báo lỗi và lọc ra vấn đề quan trọng và trả về nó. Nó cũng lưu vị trí hiện tại của tệp nhật ký để lần sau nó phải đọc nhật ký, nó có thể bắt đầu từ vị trí còn lại thay vì đọc toàn bộ nhật ký một lần nữa. Việc này được thực hiện bằng cách sử dụng chức năng cho biết chức năng.

Tôi có ý tưởng sử dụng lệnh ghép ngắn Get-Content và bắt đầu đọc ở vị trí cuối cùng, xử lý từng dòng cho đến khi kết thúc tệp và sau đó lưu vị trí.

Bạn có biết bất kỳ thủ thuật nào để tôi có thể lấy vị trí trong tệp nhật ký sau khi đọc và bắt đầu đọc tại một vị trí cụ thể không.

Hoặc có cách nào tốt hơn và/hoặc dễ dàng hơn để đạt được điều này không?

Gísli

CHỈNH SỬA: Việc này phải được thực hiện thông qua tập lệnh chứ không phải với một số công cụ khác.

EDIT: Vì vậy, tôi đang nhận được một nơi nào đó với các.NET API nhưng nó không hoàn toàn làm việc cho tôi. Tôi tìm thấy một liên kết hữu ích herehere

Dưới đây là những gì tôi có cho đến nay:

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" 
    } 
} 

}

tôi đã không tìm thấy một cách để sử dụng chức năng tìm kiếm chính xác. Ai đó có thể chỉ cho tôi đi đúng hướng?

Nếu tôi chạy nó này đầu ra 5270 nhưng nếu tôi chạy này với ra đường, nơi tôi cố gắng tìm kiếm trong các dòng cơ bản tôi nhận được:

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 

Trường hợp phần đầu tiên là dòng đọc từ nhật ký và số ở cuối đại diện cho các byte được đọc tại thời điểm đó. Vì vậy, như bạn có thể thấy tôi đang cố gắng sử dụng chức năng tìm kiếm để bỏ qua dòng lỗi đầu tiên nhưng như tôi đã nói trước đó đầu ra là 5270 nếu tôi sử dụng chức năng tìm kiếm.

Tôi đang thiếu gì ?????

Gísli

+0

+1 để đề cập đến hàm [tellper (http://perldoc.perl.org/functions/tell.html). Tôi đã không nghe nói về nó trước đây. Chỉ cần tự hỏi, bạn có mong đợi viết lại kịch bản được ít khó khăn hơn so với cài đặt Perl hoặc là có một vấn đề yêu cầu liên quan? –

+0

Viết lại là địa ngục nếu đó là những gì bạn đang yêu cầu. Vấn đề là chúng tôi giám sát cơ sở dữ liệu cho người khác và điều này sẽ làm cho việc thiết lập dễ dàng hơn tại các máy chủ Windows mới trong tương lai. Tôi cũng nên đề cập rằng tôi là một thực tập sinh vào mùa hè này và dự án này cũng là một cách để cho tôi tìm hiểu mã và hiểu những gì các kịch bản đang làm. Và họ cũng muốn ai đó bắt đầu học PowerShell. Vì vậy, trong ngắn hạn, nó có lẽ sẽ dễ dàng hơn để cài đặt perl và sử dụng kịch bản đó. – Gisli

+0

không hoàn toàn chắc chắn những gì bạn đang yêu cầu tại thời điểm này - tôi sẽ có một đọc nhưng kiểm tra các biến của bạn - $ l là sự trở lại của sự chia rẽ nhưng bạn đang viết $ line - bạn có nghĩa là? – Matt

Trả lời

2

có lẽ bạn sẽ có thể làm điều này với một số đối tượng .net vv ...

Nếu đó là một định dạng tiêu chuẩn hơn log file tôi không nhìn nhiều quá khứ logparser mặc dù. Thật tuyệt vời trước thời gian và vẫn tuyệt vời!

Bạn có thể sử dụng thông qua dòng lệnh hoặc COM bằng PowerShell. Nó có khả năng đánh dấu nó ở đâu trong một tập tin và nhận từ đó (lưu trữ thông tin trong một tập tin lpc).

Có thể ai đó sẽ đưa ra một cách tốt để làm điều này, nhưng nếu không bạn cũng có thể xem xét chuyển đổi để ghi thông tin lỗi cho người xem sự kiện. Bạn có thể lưu trữ id cuối cùng hoặc lần cuối cùng bạn tìm kiếm trình xem sự kiện và kiểm tra từ đó mỗi lần.

hy vọng có điều gì đó tốt hơn ...

EDIT:

Nếu tập tin được phân định tab bạn có thể sử dụng lệnh nhập csv và lưu trữ các số cuối cùng (nó muốn thể được đếm hoặc đếm-1 nếu các tiêu đề được bao gồm trong số). Với số cuối cùng, bạn có thể chuyển đến điểm cuối cùng trong tệp

# use Import-CliXML to get the $last_count 
Import-CliXML $path_to_last_count_xml 
$file = Import-Csv filename -delimiter "`t" 
for ($i=$last_count; $i -gte $file.count; $i++) { 
    $line = $file[$i] 
    # do something with $line 
    ... 
} 
$last_count = $file.count | Export-CliXML $path_to_last_count_xml 

# use this to clear the memory 
Remove-Variable $file 
[GC]::collect 

hoặc bạn có thể truy vấn trực tiếp DB bằng sp_readerrorlog; sử dụng lần cuối như số cuối cùng ở trên.

+0

Cảm ơn. Nếu tôi hiểu bạn một cách chính xác, logparser là một công cụ mà tôi sẽ cần tải xuống và cài đặt. Lý do tại sao kịch bản được viết lại trong PowerShell là để chúng tôi không phải cài đặt perl trên các máy chủ Windows mới mà chúng tôi đang theo dõi. Vì vậy, mặc dù đây là một công cụ tốt, chúng tôi cũng có thể cài đặt perl trên máy và bỏ qua viết lại. Thanks anyway – Gisli

+0

yeah đó là ... định dạng tệp nhật ký của bạn là gì? – Matt

+0

Đây là lỗi mà máy chủ MSSQL tạo ra. Nó là một tập tin văn bản đơn giản không có phần mở rộng (tập tin loại 'tập tin') – Gisli

0

Có hai tùy chọn tôi sẽ đề xuất nếu bạn thực sự muốn sử dụng PowerShell.

  1. Sử dụng API tệp .NET.

  2. Đọc toàn bộ nội dung nhật ký và sau đó xóa nội dung đó. Lưu trữ nội dung được phân tích cú pháp trong cơ sở dữ liệu.

+0

cảm ơn cho tip. Tôi sẽ xem xét nó vào ngày mai – Gisli

1

Nếu mục tiêu của bạn là chỉ đọc tệp từ dòng cuối cùng được đọc trong lần chạy trước Vui lòng bỏ qua câu trả lời này. Tuy nhiên, nếu bạn chỉ đang cố gắng nhận bất kỳ lỗi nào kể từ lần kiểm tra cuối cùng thì điều này có thể hữu ích.


[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 

Nếu bạn pick-up thời gian chạy cuối cùng từ một tập tin, hoặc chỉ biết bạn chạy mỗi giờ hoặc bất cứ điều gì, bạn có thể điều chỉnh $ chkDate để chỉ hiển thị lỗi từ đó đến cuối của tập tin.

(xem ra cho những back-ve (') vào cuối năm (0) dòng $ srvObj.ReadErrorLog và dòng tiếp theo. Họ không phải lúc nào đi ra cho tôi trong HTML)

+0

Cảm ơn bạn đã trả lời. Mục tiêu là chỉ đọc tệp.Nhưng bạn có một liên kết để tôi có thể đọc thêm một chút về các chức năng bạn đang sử dụng hay không. Giống như ReadErrorLog, LogDate, Text. Tôi sợ mã của bạn hơi phức tạp đối với tôi vào thời điểm này nhưng tôi muốn hiểu nó. – Gisli

+0

Bạn có thể nhận được điều gì đó từ bài viết này tại Hey, Scripting Guy http://blogs.technet.com/b/heyscriptingguy/archive/2011/05/31/use-powershell-to-get-the-sql-server- error-log.aspx Phiên bản SMO gần như ở cuối trang. Ngoài ra còn có một liên kết đến lớp Server từ Microsoft.SQLServer.SMO .NET Framework tại MSDN. – Bruce

Các vấn đề liên quan