带有Powershell的石墨

pri*_*ero 6 powershell tcp graphite

我在一个服务器上配置了一个石墨实例,并且我正在用它来监视我的环境,可悲的是它同时包含linux和Windows机器。我想监视服务器的运行状况,因此我选择在Linux机器上进行collectl,这在收集系统统计信息方面做得很好。

可悲的是,对于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
}
Run Code Online (Sandbox Code Playgroud)

现在,此脚本输出的内容乍一看。输出具有格式,hostname.metrics.name $metric_value $epochTime但是没有图形在绘制。它们出现在石墨仪表板上,但它们是空的。我检查了通过wireshark发送到石墨服务器的输出。它表明,在Windows中,消息仅带有CRLF,而在Linux中则只有LF。我\n手动添加了一段时间,它成功了,但是现在它停止工作了。

我的问题是我在传输中做错了吗,因为我一直在分析流量,因此,从Linux机器获得图表和从Windows中获得图表的流量之间的唯一区别是行终止符。在linux中,它的LF(0a)和在Windows中是CRLF(0d0a),但是我再次尝试从linux发送LFCRLF(0a0d0a),希望石墨服务器只读取直到第一个LF并隐传消息,但是我仍然我没有图。

另外,当我从linux传输时,我只有一条消息,而当我从powershell传输时,我只有三条消息。根据我在碳缓存过程中使用strace所看到的,我有一个recvfrom系统调用,并带有我想要的消息,而我有另一个是空的,并且写syscall(当从powershell传输时)相反。一条消息,一次写一个recvfrom(在Linux上用netcat传输时),

pri*_*ero 3

似乎没有人提供任何建议,因此我采用了另一种方法。我仍然很好奇为什么 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 
    }
}
Run Code Online (Sandbox Code Playgroud)

该脚本是可扩展的,你可以监控很多东西,只需运行get-counter -ListSet *你就会看到。我已经使用 TaskScheduler 安装了脚本,您可以通过插入睡眠来控制 while 循环的频率。