Graphite with powershell

I have a graphite instance configured on one server, and I use it to monitor my environment, which, unfortunately, consists of linux and windows machines. I want to monitor the well-being of my servers, so I chose a collector on my Linux machines that does a great job with statistics statistics.

Sadly for windows, it seems there are not many solutions for getting system statistics and sending them to graphite, but I managed to deal with this situation using powershell. I am using a script that was suggested here http://josh.behrends.us/2012/07/windows-powershell-graphite-awesome/ for graphite connection as well as for getting metrics from a computer I am using get-counter comandlet which , surprisingly, can gather a lot of information.

My script looks like this:

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 } 

Now this script displays what it should at first glance. The output is in the format hostname.metrics.name $metric_value $epochTime , but there are no graphs. They appear on the graphite panel, but they are empty. I checked the output sent to the graphite server with wirehark. It’s seams that in windows a message is added with CRLF unlike Linux, where you have only LF. I added \n manually, and for a short period of time it did the trick, but now it has stopped working.

My question is that I am doing something wrong in the transfer because I analyzed trafic and the only difference between the stream forms of linux machines that receive graphed and those that do not receive graphed from the windows are line terminators. In linux its LF (0a) and in windows is CRLF (0d0a), but again I tried to send from linux LFCRLF (0a0d0a) hoping that the graphite server will only read until the first LF, not an interepret message, but still I do not receive schedules.

Also, when I submit from linux, I only have one message, and when I submit the powershell form, I have three messages. From what I saw using strace in the cache cache process, I have one system call with the message I want, and I have another that is empty, and a SIX script to write (when transferring from powershell), unlike yo, one message per message and one message (when transferring from netcat to linux),

+4
source share
2 answers

Nobody seemed to offer any suggestions, and so I took a different approach. I am still very curious why Graphite does not interpret my sent message. The solution to this problem was to use a UDP socket instead of the TCP protocol and send metrics to statsd, which in terms of sends them to Graphite. It seems to work without any complications, and if you think about it, it is better for your network because it minimizes traffic (if you keep statsd and Graphite on the same node).

I post a script if anyone encounters my problem and its environment is similar to mine. Here is the script

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

The script is extensible and you can track many things, just run get-counter -ListSet * and you will see. I installed a script with TaskScheduler, and you can control the frequency with a while loop by inserting sleep mode.

+1
source

I made a number of PowerShell functions that are useful for simply sending metrics to graphite. You can configure all Windows performance counters and how often they are sent to the Graphite server. The full source code is here: https://github.com/MattHodge/Graphite-PowerShell-Functions

0
source

Source: https://habr.com/ru/post/1442705/


All Articles