Last active
November 24, 2015 15:56
-
-
Save batmat/e67e661656c3d31ed36f to your computer and use it in GitHub Desktop.
Quick & certainly fragile script to gather informations from a docker swarm daemon /info Cf. https://github.com/docker/swarm/issues/735 for the clean way some day. Push to graphite also supported (see the end of the script)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Quick & certainly fragile script to gather informations from a docker swarm daemon /info | |
// Cf. https://github.com/docker/swarm/issues/735 for the clean way some day | |
import groovy.json.* | |
def swarmInfoUrl = 'http://sv-t-vnl-ic-swarm:3375/info' | |
def graphiteHost = 'sv-t-vnl-forge-metrics' | |
def graphitePort = 2003 | |
def nodeReservedMemoryField = 'reservedmemory' | |
def nodeTotalMemoryField = 'totalmemory' | |
def graphitePrefix = 'swarm' | |
/** converts an array of arrays of 2 elements to a map keyed with the first | |
* element of each array, and the value with the second one. | |
*/ | |
def array2ToMap = { array2 -> | |
def map = [:] | |
array2.each { a,b -> | |
map[a] = b | |
} | |
map | |
} | |
/////////// | |
def jsonSlurper = new JsonSlurper() | |
def json = swarmInfoUrl.toURL().text | |
// See https://github.com/docker/swarm/issues/735 again | |
// Cleaning characters | |
json = json | |
.replaceAll('\\\\u0008','') | |
.replaceAll(' └ ','') | |
def dockerInfo = jsonSlurper.parseText(json) | |
def driverStatus = dockerInfo.DriverStatus | |
// From index 0 to 3 are the generic infos about the Swarm | |
def generalInformations = array2ToMap(driverStatus[0..3]) | |
def nodes = driverStatus[4..driverStatus.size()-1] | |
def nodesMap = [:] | |
for (int i = 0; i<nodes.size(); i = i+5) { | |
def nodeArray = nodes[i..i+4] | |
nodesMap[nodes[i][0]] = array2ToMap(nodes[i+1..i+4]) | |
//println nodeArray.Containers | |
} | |
// Transform "Reserved* to make it usable as metrics" | |
// as "Reserved Memory:17.58 GiB / 36.96 GiB" isn't | |
nodesMap.each { nodeName,values -> | |
def rawReservedMemory = values["Reserved Memory"] | |
assert rawReservedMemory != "" | |
def reservedMemory = rawReservedMemory.replaceAll(' ','').replaceAll('GiB','').split('/') | |
values[nodeReservedMemoryField] =reservedMemory[0] | |
values[nodeTotalMemoryField] = reservedMemory[1] | |
nodesMap[nodeName] = values | |
} | |
///////////// Some display to demo / log | |
println "Global informations:" | |
println "\tContainers: ${dockerInfo.Containers}" | |
generalInformations.each { entry -> | |
println "\t${entry.key} => ${entry.value}" | |
} | |
println "Per node informations" | |
nodesMap.each { entry -> | |
println "\t${entry.key} => \n\t\t ${entry.value}" | |
} | |
/////////////////////////////// | |
// Push to graphite | |
def metrics = [ | |
["containers",dockerInfo.Containers], | |
["memtotal",dockerInfo.MemTotal], | |
["images",dockerInfo.Images], | |
["ncpu",dockerInfo.NCPU], | |
["nfd",dockerInfo.NFd], | |
["ngoroutines",dockerInfo.NGoroutines], | |
["nodes",generalInformations['Nodes']] | |
] | |
nodesMap.each { key, value -> | |
def nodeName = key.substring(0, key.indexOf('.')) | |
metrics.push (["$nodeName.$nodeReservedMemoryField",value[nodeReservedMemoryField]]) | |
metrics.push (["$nodeName.$nodeTotalMemoryField",value[nodeTotalMemoryField]]) | |
} | |
long timestamp = System.currentTimeMillis()/1000L; | |
def message = "" | |
metrics.each { metricName, metricValue -> | |
message += "$graphitePrefix.$metricName $metricValue $timestamp\n" | |
} | |
println "Gonna send <$message>" | |
def socket = new Socket(graphiteHost, graphitePort) | |
socket.withStreams { input, output -> | |
output << message | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Expected output (and naming scheme essentially) :