2012-10-29 181 views
4

我有一個配置在一臺服務器上的石墨實例,我用它來監視我的環境,可悲的是由Linux和Windows機器組成。我想監視我的服務器的健康狀況,所以我選擇了在我的linux機器上收集collectl的系統統計信息。石墨與powershell

不幸的是,對於windows來說,獲取系統統計信息並將它們發送給石墨似乎並沒有太多解決方案,但我已經設法通過PowerShell處理這種情況。我正在使用這裏建議的腳本http://josh.behrends.us/2012/07/windows-powershell-graphite-awesome/用於石墨連接,也用於從計算機中獲取指標 我使用的是get-counter comandlet,它令人驚訝地可以收集大量信息。

我的劇本是這樣的:

while (1 -eq 1) 
{ 
$carbonServer = "hostname" 
$carbonServerPort = 2003 
$epochtime = [int][double]::Parse((Get-Date -UFormat %s)) 

$socket = New-Object System.Net.Sockets.TCPClient 
$socket.connect($carbonServer, $carbonServerPort) 
$stream = $socket.GetStream() 
$writer = new-object System.IO.StreamWriter($stream) 
#Write out metric to the stream. 

$DiskQue = [int]((get-counter -Counter "\PhysicalDisk(1 e: f:)\Current Disk Queue Length").countersamples | select -property cookedvalue).cookedvalue 
$BytesReceived = [int]((get-counter -Counter "\Server\Bytes Received/sec").countersamples | select -property cookedvalue).cookedvalue 
$BytesSent = [int]((get-counter -Counter "\Server\Bytes Transmitted/sec").countersamples | select -property cookedvalue).cookedvalue 
$MemAvail = ((get-counter -Counter "\Memory\Available Bytes").countersamples | select -property cookedvalue).cookedvalue 
$MemCommit = ((get-counter -Counter "\Memory\Committed Bytes").countersamples | select -property cookedvalue).cookedvalue 
$ReadOp = [int]((get-counter -Counter "\System\File Read Operations/sec").countersamples | select -property cookedvalue).cookedvalue 
$WriteOp = [int]((get-counter -Counter "\System\File Write Operations/sec").countersamples | select -property cookedvalue).cookedvalue 

$metric7 = ("hostname.metrics.WriteOp " + $WriteOp + " " + $epochTime+"`n") 
$metric7 

$writer.WriteLine($metric7) 
$writer.Flush() #Flush and write our metrics. 
$writer.Close() 
$stream.Close() 
sleep 5 
} 

現在這個腳本輸出什麼它應該乍一看。輸出格式爲hostname.metrics.name $metric_value $epochTime,但沒有繪製圖表。他們在石墨儀表板中黯然失色,但空空如也。我檢查了用wireshark發送到石墨服務器的輸出。它在Windows中接收消息後附加了CRLF,而不是隻有LF的Linux。我手動添加了\n,並在一小段時間內完成了這項工作,但現在停止工作。

我的問題是我在傳輸過程中做錯了什麼,因爲我一直在分析交通,從得到圖形的Linux機器和從沒有得到圖形的窗口傳來的流量之間的唯一區別就是線路終結器。在linux下它的LF(0a)和windows是CRLF(0d0a),但是我試圖從linux LFCRLF(0a0d0a) 發送,希望石墨服務器只讀直到第一個LF,並且不是inteIn的消息,但仍然是我不是圖表。

另外,當我從linux傳輸我只有一個消息,當我傳輸形式PowerShell我有三個消息。從我在碳緩存過程中看到的strace,我有一個recvfrom系統調用與我想要的消息,並且我有另一個是空的,寫系統調用(當從powershell發送時),而不是喲只有一個recvfrom與消息和寫(當與netcat在Linux上傳輸時),

回答

1

似乎沒有人提供任何建議,因此我採取了另一種方法。我仍然很好奇爲什麼Graphite不解釋我發送的消息。此問題的解決方案是使用UDP套接字而不是TCP套接字,並將度量標準發送到statsd,然後將其發送到Graphite。這似乎沒有任何複雜性,並且如果您考慮它,它對網絡更好,因爲它可以最大限度地減少流量(如果將statsd和Graphite保留在同一節點上)。

我發佈腳本以防萬一遇到我的問題,他的環境就像我的。這裏是腳本

[int] $Port = 8125 
$IP = "here is your IP" 
$Address = [system.net.IPAddress]::Parse($IP) 
$End = New-Object System.Net.IPEndPoint $address, $port 
$Saddrf = [System.Net.Sockets.AddressFamily]::InterNetwork 
$Stype = [System.Net.Sockets.SocketType]::Dgram 
$Ptype = [System.Net.Sockets.ProtocolType]::UDP 
$Sock  = New-Object System.Net.Sockets.Socket $saddrf, $stype, $ptype 
$sock.Connect($end) 

function Send_Graphite 
{param ($Metric) 

$Enc  = [System.Text.Encoding]::ASCII 
$Buffer = $Enc.GetBytes($Metric) 
$Sent = $Sock.Send($Buffer) 
"{0} characters sent to: {1} " -f $Sent,$IP 
"Message is:" 
$Metric 
sleep 1 

} 

while (1 -eq 1) 
{ 
    $DiskQue = [int]((get-counter -Counter "\PhysicalDisk(1 e: f:)\Current Disk Queue Length").countersamples | select -property cookedvalue).cookedvalue 
    $BytesReceived = [int]((get-counter -Counter "\Server\Bytes Received/sec").countersamples | select -property cookedvalue).cookedvalue 
    $BytesSent = [int]((get-counter -Counter "\Server\Bytes Transmitted/sec").countersamples | select -property cookedvalue).cookedvalue 
    $MemAvail = ((get-counter -Counter "\Memory\Available Bytes").countersamples | select -property cookedvalue).cookedvalue 
    $MemCommit = ((get-counter -Counter "\Memory\Committed Bytes").countersamples | select -property cookedvalue).cookedvalue 
    $ReadOp = [int]((get-counter -Counter "\System\File Read Operations/sec").countersamples | select -property cookedvalue).cookedvalue 
    $WriteOp = [int]((get-counter -Counter "\System\File Write Operations/sec").countersamples | select -property cookedvalue).cookedvalue 

    $Message1 = "MAIN.OSmetrics.DiscQueue:"+$DiskQue+"|c" 
    $Message2 = "MAIN.OSmetrics.BytesReceived:"+$BytesReceived+"|c" 
    $Message3 = "MAIN.OSmetrics.BytesSent:"+$BytesSent+"|c" 
    $Message4 = "MAIN.OSmetrics.MemAvail:"+$MemAvail+"|c" 
    $Message5 = "MAIN.OSmetrics.MemCommit:"+$MemCommit+"|c" 
    $Message6 = "MAIN.OSmetrics.ReadOp:"+$ReadOp+"|c" 
    $Message7 = "MAIN.OSmetrics.WriteOp:"+$WriteOp+"|c" 

    $Mesages = $Message1, $Message2, $Message3, $Message4, $Message5, $Message6, $Message7 
    foreach($Message in $Mesages) 
    { 
     Send_Graphite $Message 
    } 
} 

劇本是可擴展的,可以監視很多事情,只要運行get-counter -ListSet *,你會看到。我已經使用TaskScheduler安裝了該腳本,並且可以通過插入睡眠來使用while循環控制頻率。

0

我做了一系列PowerShell函數,這些函數可以很方便地將度量指標發送給Graphite。您可以配置所有Windows性能計數器以及希望它們發送到Graphite服務器的頻率。完整的源代碼在這裏:https://github.com/MattHodge/Graphite-PowerShell-Functions