Thanks for the reply. As it turns out, I did end up getting this to work correctly, though now I am unsure what I did
As requested, here is the code for the component:
/**
*
* @name Custom Statistics
* @category analysis
* @id com.example.CustomStatistics
*/
//Properties
createProperty('stats', String, '')
customStats = [:]
createStats = {
if(customStats) {
for(stat in customStats) {
log.info("Removing stat " + stat.key)
removeStatisticVariable(stat.key)
}
customStats = [:]
}
if(!stats.value) {
return [:]
}
log.debug("Parsing stats String $stats.value")
splitStats = stats.value.split(' *, *')
log.debug("Split stats=$splitStats")
ret = [:]
for(stat in splitStats) {
splitStat = stat.split(':')
def statName = splitStat[0]
def statType = 'SAMPLE'
if(splitStat.length > 1) {
statType = splitStat[1]
}
log.info("Adding new stats variable '$statName' of type '$statType'")
newStat = addStatisticVariable(statName, statType)
ret[statName] = newStat
}
customStats = ret
}
analyze = { message ->
now = System.currentTimeMillis()
try {
if(message instanceof Map) {
if(message['stats'] instanceof Map) {
theseStats = message['stats']
for(customStatEntry in customStats) {
statName = customStatEntry.key
stat = customStatEntry.value
statValue = theseStats[statName]?.value
if(statValue) {
try {
//log.info("Updating stat $statName: $statValue")
if(statValue instanceof Number) {
stat.update(now, statValue)
}
else if(statValue instanceof String) {
stat.update(now, Long.parseLong(statValue))
}
else {
log.error("value for stat '$statName' is not a Number or String! : $statValue")
}
} catch(NumberFormatException ignored) {
log.error("Unable to parse value for stat '$statName'", e)
}
}
else {
log.error("No value for stat '$statName'")
}
}
}
}
}
catch(Exception e) {
log.error('analyze', e)
}
}
collectStatisticsData = {
log.debug("In collectStatisticsData")
}
handleStatisticsData = { statisticsData ->
log.debug("handleStatisticsData: $statisticsData")
}
onAction("RESET") {
createStats()
}
layout {
box( layout: 'wrap 2, ins 0' ) {
property( property: stats, label: 'Expected Statistics', constraints: 'growx, spanx 2' )
}
}
createStats()
onReplace(stats, createStats)
Basically, you input a comma-delimited set of expected stat names (and optionally type) and the component registers a new statistic variable with that name and type. Then, it expects that the message passed in contains a key called 'stats' whose value is another map where the keys are stat names and the values are the numeric values to pass to the stat.update() method. I hope that makes sense.
Like I said, this was kind of quick and dirty component and there are definitely some improvements that could be made, but it seems to get the job done!
By the way, since I have you on the line, I was wondering if there was any way to clear the System Log and/or set the number of log entries that are kept? Since I've been dabbling in writing custom components, once in a while I'll see a stack trace get generated, but I can't get to it before it is pushed off the log by newer entries.
Thanks again!