Skip to content

Commit

Permalink
#56 fixing a problem where the host object (which now includes timezo…
Browse files Browse the repository at this point in the history
…ne) is used to work out the index offset to write temperatures to the RRD and not just the host name
  • Loading branch information
tobyweston committed Feb 17, 2018
1 parent e874e83 commit 6badec9
Show file tree
Hide file tree
Showing 4 changed files with 25 additions and 16 deletions.
4 changes: 2 additions & 2 deletions src/main/scala/bad/robot/temperature/rrd/Host.scala
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,12 @@ object Host {
}

def local = Host(InetAddress.getLocalHost.getHostName, localUtcOffset)

implicit val encoder = deriveEncoder[Host]
implicit val decoder = deriveDecoder[Host]

// another arbitrary constraint of rrd4j; data source names can only be a max of 20 characters
def trim(name: String) =name.take(20 - "-sensor-x".length)
def trim(name: String) = name.take(20 - "-sensor-x".length)
}

case class Host(name: String, utcOffset: Option[String])
2 changes: 1 addition & 1 deletion src/main/scala/bad/robot/temperature/rrd/Rrd.scala
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,5 @@ package bad.robot.temperature.rrd
import bad.robot.temperature.{Measurement, TemperatureWriter}

case class Rrd(monitored: List[Host]) extends TemperatureWriter {
def write(measurement: Measurement) = RrdUpdate(monitored, measurement).apply()
def write(measurement: Measurement) = RrdUpdate(monitored).apply(measurement)
}
27 changes: 18 additions & 9 deletions src/main/scala/bad/robot/temperature/rrd/RrdUpdate.scala
Original file line number Diff line number Diff line change
Expand Up @@ -4,29 +4,38 @@ import bad.robot.logging.Log
import bad.robot.temperature.{Error, Measurement, RrdError, SensorReading, Temperature, _}
import org.rrd4j.core.RrdDb

import scalaz.\/
import scalaz.{\/, \/-}
import scalaz.\/.fromTryCatchNonFatal

case class RrdUpdate(monitored: List[Host], measurement: Measurement) {
case class RrdUpdate(monitored: List[Host]) {

private val UnknownValues = List().padTo(monitored.size * RrdFile.MaxSensors, SensorReading("Unknown", Temperature(Double.NaN)))

def apply(): Error \/ Unit = {
def apply(measurement: Measurement): Error \/ Unit = {
indexOf(measurement) match {
case Some(index) => writeTemperatureAt(measurement, index)
case None => Log.error(s"Unable to write temperature to RRD: '${measurement.host.name}' not setup as an archive"); \/-(())
}
}

private def writeTemperatureAt(measurement: Measurement, index: Int) = {
fromTryCatchNonFatal {
val database = new RrdDb(RrdFile.file)
val sample = database.createSample()
val indexOf = monitored.indexOf(measurement.host)
Log.debug(s"Index of ${measurement.host.name } is $indexOf (-1 means it couldn't be found)")
val temperatures = UnknownValues.patch(indexOf * RrdFile.MaxSensors, measurement.temperatures, measurement.temperatures.size)
val temperatures = UnknownValues.patch(index * RrdFile.MaxSensors, measurement.temperatures, measurement.temperatures.size)
sample.setValues(database, measurement.time, temperatures.map(_.temperature.celsius): _*)
Log.debug(s"rrd -> ${measurement.host.name} ${measurement.time} ${temperatures.map(t => t.name + " " + t.temperature.celsius).mkString(", ")}")
database.close()
}.leftMap(error => {
RrdError(messageOrStackTrace(error))
})
}

def messageOrStackTrace(error: Throwable): String = {
Option(error.getMessage).getOrElse(stackTraceOf(error))
private def indexOf(measurement: Measurement): Option[Int] = {
val index = monitored.map(_.name).indexOf(measurement.host.name)
if (index == -1) None else Some(index)
}

private def messageOrStackTrace(error: Throwable): String = {
Option(error.getMessage).getOrElse(stackTraceOf(error))
}
}
8 changes: 4 additions & 4 deletions src/test/scala/bad/robot/temperature/rrd/Example.scala
Original file line number Diff line number Diff line change
Expand Up @@ -48,14 +48,14 @@ object Example extends App {

times.zip(temperatures).foreach({
case (time, (temperature1, temperature2)) => {
handleError(RrdUpdate(hosts, Measurement(hosts(0), time, List(
handleError(RrdUpdate(hosts).apply(Measurement(hosts(0), time, List(
SensorReading("?", Temperature(temperature1)),
SensorReading("?", Temperature(temperature1 + 6.3)))
)).apply())
handleError(RrdUpdate(hosts, Measurement(hosts(1), time + 1, List(
)))
handleError(RrdUpdate(hosts).apply(Measurement(hosts(1), time + 1, List(
SensorReading("?", Temperature(temperature2)),
SensorReading("?", Temperature(temperature2 + 1.3)))
)).apply())
)))
}
})

Expand Down

0 comments on commit 6badec9

Please sign in to comment.