2012-10-29 4 views
4

나는 한 대의 서버에 구성된 흑연의 인스턴스를 가지고 있으며 슬프게도 리눅스와 Windows 머신으로 구성된 내 환경을 모니터하는데 사용하고있다. 나는 모니터를 잘하고 내 서버의 그래서 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를 사용하여 흑연 서버로 보낸 출력을 검사했습니다. 그것은 당신이 단지 LF를 가지고있는 리눅스와는 반대로 윈도우에서 메시지가 CRLF로 덧붙여지게됩니다. 나는 손으로 \n를 추가했다. 그리고 약간의 시간 동안 그것은 트릭을했다. 그러나 지금 그것은 멈췄다.

내 질문은 내가 트래픽을 분석 해왔고 교통 체증을 겪고있는 리눅스 머신과 그래프로 표시되지 않는 창문 사이의 유일한 차이점은 라인 터미네이터 (line terminators)라고 생각하기 때문에 전송에 문제가있다. 리눅스에서 자사의 LF (0a) 및 Windows에서 CRLF (0d0a),하지만 다시 리눅스 LFCRLF (0a0d0a) 첫 번째 LF까지 interepret 때까지 흑연 서버를 기대하고 보내려고했는데 여전히하지만 난 그래프를 얻지 못해.

또한 리눅스에서 전송할 때 단 하나의 메시지 만 있고, powershell 양식을 전송할 때 세 가지 메시지가 있습니다. 내가 카본 - 캐시 과정에서 strace로 본 것에서 나는 원하는 메시지를 가지고 하나의 recvfrom 시스템 호출을 가지고있다. 그리고 나는 비어있는 다른 것을 가지고있다. 그리고 필자는 시스템 콜을 (powershell에서 전송할 때) 반대쪽으로 보낸다. 메시지가있는 recvfrom과 쓰기 (리눅스에서 netcat으로 전송할 때),

답변

1

아무도 어떤 제안도하지 못했기 때문에 나는 다른 접근법을 따랐다. 흑연이 내 보낸 메시지를 왜 해석하지 않는지에 대해서는 여전히 궁금합니다. 이 문제에 대한 해결책은 TCP 대신 UDP 소켓을 사용하고 메트릭을 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

Graphite로 쉽게 보낼 수있는 일련의 PowerShell 함수를 만들었습니다. 모든 Windows 성능 카운터를 구성하고 Graphite 서버로 보낼 빈도를 구성 할 수 있습니다. 전체 소스 코드는 여기에 있습니다 : https://github.com/MattHodge/Graphite-PowerShell-Functions

관련 문제