Skip to content

Instantly share code, notes, and snippets.

@batmat
Last active November 24, 2015 15:56
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save batmat/e67e661656c3d31ed36f to your computer and use it in GitHub Desktop.
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)
// 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
}
@batmat
Copy link
Author

batmat commented Nov 24, 2015

Expected output (and naming scheme essentially) :

swarm.containers 15 1448380327
swarm.memtotal 57352445337 1448380327
swarm.images 30 1448380327
swarm.ncpu 24 1448380327
swarm.nfd 0 1448380327
swarm.ngoroutines 0 1448380327
swarm.nodes 2 1448380327
swarm.sv-t-vnl-ic-centos7-2.reservedmemory 16.6 1448380327
swarm.sv-t-vnl-ic-centos7-2.totalmemory 16.45 1448380327
swarm.sv-t-vnl-ic-centos7-3.reservedmemory 17.58 1448380327
swarm.sv-t-vnl-ic-centos7-3.totalmemory 36.96 1448380327

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment