Skip to content
This repository has been archived by the owner on Mar 11, 2019. It is now read-only.

Commit

Permalink
chore(build.sbt): update libraries + add a common build object to dow…
Browse files Browse the repository at this point in the history
…nload bluecove

refactoring(libraries): extract unmanaged dependencies inside a root folder

Use a root folder to store external dependencies. Fix a bug with sigar (closes #75).
  • Loading branch information
mcolmant committed Feb 2, 2016
1 parent 8b1d1d1 commit 4a40844
Show file tree
Hide file tree
Showing 133 changed files with 244 additions and 174 deletions.
4 changes: 1 addition & 3 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,5 @@ target/
.worksheet

#bluecove
*/*/bluecove*
*bluecove*

#tokens
secrets.tar
14 changes: 7 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,24 +44,24 @@ PowerAPI is used in a variety of projects to address key challenges of GreenIT:
* [Greenspector](http://greenspector.com) optimises the power consumption of software by identifying potential energy leaks in the source code.

## Acknowledgments
We all stand on the shoulders of giants and get by with a little help from our friends. PowerAPI is written in [Scala](http://www.scala-lang.org) (version 2.11.6 under [3-clause BSD license](http://www.scala-lang.org/license.html)) and built on top of:
* [Akka](http://akka.io) (version 2.3.11 under [Apache 2 license](http://www.apache.org/licenses/LICENSE-2.0)), for asynchronous processing
We all stand on the shoulders of giants and get by with a little help from our friends. PowerAPI is written in [Scala](http://www.scala-lang.org) (version 2.11.7 under [3-clause BSD license](http://www.scala-lang.org/license.html)) and built on top of:
* [Akka](http://akka.io) (version 2.3.14 under [Apache 2 license](http://www.apache.org/licenses/LICENSE-2.0)), for asynchronous processing
* [Typesafe Config](https://github.com/typesafehub/config) (version 1.2.1 under [Apache 2 license](http://www.apache.org/licenses/LICENSE-2.0)), for reading configuration files.
* [Apache log4j2](http://logging.apache.org/log4j/2.x) (version 2.3 under [Apache 2 license](http://www.apache.org/licenses/LICENSE-2.0)), for logging outside actors.
* [Apache log4j2](http://logging.apache.org/log4j/2.x) (version 2.5 under [Apache 2 license](http://www.apache.org/licenses/LICENSE-2.0)), for logging outside actors.
* [powerspy.scala](https://github.com/Spirals-Team/powerspy.scala) (version 1.2 under [AGPL license](http://www.gnu.org/licenses/agpl-3.0.html)), for using the [PowerSpy powermeter](http://www.alciom.com/en/products/powerspy2-en-gb-2.html).
* [BridJ](https://code.google.com/p/bridj/) (version 0.7.0 under [3-clause BSD license](https://github.com/ochafik/nativelibs4java/blob/master/libraries/BridJ/LICENSE)), for system or C calls.
* [JNA](https://github.com/twall/jna) (version 4.1.0 under [LGPL 2.1 license](https://github.com/twall/jna/blob/master/LGPL2.1)), for system or C calls.
* [JNA](https://github.com/twall/jna) (version 4.2.1 under [LGPL 2.1 license](https://github.com/twall/jna/blob/master/LGPL2.1)), for system or C calls.
* [perfmon2](http://sourceforge.net/p/perfmon2/libpfm4/ci/master/tree) (version 4.6.0 under [MIT license](http://sourceforge.net/p/perfmon2/libpfm4/ci/master/tree/COPYING)), for accessing hardware performance counters.
* [JFreeChart](http://www.jfree.org/jfreechart/) (version 1.0.19 under [LGPL license](https://www.gnu.org/licenses/lgpl.html)), for creation of interactive and animated charts.
* [Scala IO](http://jesseeichar.github.io/scala-io-doc/0.4.3/index.html#!/overview) (version 0.4.3 under [3-clause BSD license](http://www.scala-lang.org/license.html)), for an extensions of IO.
* [Saddle](http://saddle.github.io/) (version 1.3.3 under [Apache 2 license](http://www.apache.org/licenses/LICENSE-2.0)), for data manipulation.
* [Saddle](http://saddle.github.io/) (version 1.3.4 under [Apache 2 license](http://www.apache.org/licenses/LICENSE-2.0)), for data manipulation.
* [Sigar](https://support.hyperic.com/display/SIGAR/Home) (version 1.6.5 under [Apache 2 license](http://www.apache.org/licenses/LICENSE-2.0)), for providing a portable interface for gathering system information.
* [spray-can](http://spray.io/) (version 1.3.3 under [Apache 2 license](http://www.apache.org/licenses/LICENSE-2.0)), for providing a low-level, low-overhead, high-performance HTTP server and client.
* [spray-client](http://spray.io/) (version 1.3.3 under [Apache 2 license](http://www.apache.org/licenses/LICENSE-2.0)), for providing high-level HTTP client.
* [spray-routing](http://spray.io/) (version 1.3.3 under [Apache 2 license](http://www.apache.org/licenses/LICENSE-2.0)), for providing a high-level, very flexible routing DSL for elegantly defining RESTful web services.
* [spray-json](http://spray.io/) (version 1.2.2 under [Apache 2 license](http://www.apache.org/licenses/LICENSE-2.0)), for (de)serializing JSON.
* [nscala-time](https://github.com/nscala-time/nscala-time) (version 2.0.0 under [Apache 2 license](http://www.apache.org/licenses/LICENSE-2.0)), for using a scala wrapper for Joda Time (quality replacement for the Java date and time classes).
* [docker-java](https://github.com/docker-java/docker-java) (version 2.1.1 under [Apache 2 license](http://www.apache.org/licenses/LICENSE-2.0)), for using the JAVA Docker API.
* [nscala-time](https://github.com/nscala-time/nscala-time) (version 2.8.0 under [Apache 2 license](http://www.apache.org/licenses/LICENSE-2.0)), for using a scala wrapper for Joda Time (quality replacement for the Java date and time classes).
* [docker-java](https://github.com/docker-java/docker-java) (version 2.1.4 under [Apache 2 license](http://www.apache.org/licenses/LICENSE-2.0)), for using the JAVA Docker API.

# License
This software is licensed under the *GNU Affero General Public License*, quoted below.
Expand Down
17 changes: 2 additions & 15 deletions build.sbt
Original file line number Diff line number Diff line change
@@ -1,20 +1,7 @@
name := "powerapi"

version in ThisBuild := "3.4"

scalaVersion in ThisBuild := "2.11.6"

scalacOptions in ThisBuild ++= Seq(
"-language:reflectiveCalls",
"-language:implicitConversions",
"-feature",
"-deprecation"
)

// Logging
libraryDependencies in ThisBuild ++= Seq(
"org.apache.logging.log4j" % "log4j-api" % "2.3",
"org.apache.logging.log4j" % "log4j-core" % "2.3"
"org.apache.logging.log4j" % "log4j-api" % "2.5",
"org.apache.logging.log4j" % "log4j-core" % "2.5"
)

parallelExecution in (ThisBuild, Test) := false
File renamed without changes.
File renamed without changes.
43 changes: 17 additions & 26 deletions powerapi-cli/build.sbt
Original file line number Diff line number Diff line change
@@ -1,35 +1,26 @@
name := "powerapi-cli"

lazy val downloadBluecoveApp = taskKey[File]("download-bluecove-app")
lazy val downloadBluecoveGplApp = taskKey[File]("download-bluecove-gpl-app")

downloadBluecoveApp := {
val locationBluecove = baseDirectory.value / "lib" / "bluecove-2.1.0.jar"
if(!locationBluecove.getParentFile.exists()) locationBluecove.getParentFile.mkdirs()
if(!locationBluecove.exists()) IO.download(url("https://bluecove.googlecode.com/files/bluecove-2.1.0.jar"), locationBluecove)
locationBluecove
}

downloadBluecoveGplApp := {
val locationBluecoveGpl = baseDirectory.value / "lib" / "bluecove-gpl-2.1.0.jar"
if(!locationBluecoveGpl.getParentFile.exists()) locationBluecoveGpl.getParentFile.mkdirs()
if(!locationBluecoveGpl.exists()) IO.download(url("https://bluecove.googlecode.com/files/bluecove-gpl-2.1.0.jar"), locationBluecoveGpl)
locationBluecoveGpl
}
mappings in Universal += downloadBluecove.value -> s"lib/${downloadBluecove.value.name}"

mappings in Universal += downloadBluecoveApp.value -> s"lib/${downloadBluecoveApp.value.name}"
mappings in Universal += downloadBluecoveGpl.value -> s"lib/${downloadBluecoveGpl.value.name}"

mappings in Universal += downloadBluecoveGplApp.value -> s"lib/${downloadBluecoveGplApp.value.name}"
mappings in Universal ++= {
val dir = baseDirectory.value.getParentFile

(for {
(file, relativePath) <- (dir * "README*" --- dir) pair relativeTo (dir)
} yield file -> s"$relativePath") ++
(for {
(file, relativePath) <- (dir * "LICENSE*" --- dir) pair relativeTo (dir)
} yield file -> s"$relativePath")
}

mappings in Universal ++= {
((file("../") * "README*").get map {
readmeFile: File =>
readmeFile -> readmeFile.getName
}) ++
((file("../") * "LICENSE*").get map {
licenseFile: File =>
licenseFile -> licenseFile.getName
})
val dir = baseDirectory.value.getParentFile / "external-libs" / "sigar-bin"

for {
(file, relativePath) <- (dir.*** --- dir) pair relativeTo(dir)
} yield file -> s"/lib/sigar-bin/$relativePath"
}

scriptClasspath ++= Seq("../conf", "../scripts")
Expand Down
24 changes: 6 additions & 18 deletions powerapi-core/build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -9,27 +9,27 @@ resolvers ++= Seq(

// App
libraryDependencies ++= Seq(
"com.typesafe.akka" %% "akka-actor" % "2.3.11",
"com.typesafe.akka" %% "akka-actor" % "2.3.14",
"com.typesafe" % "config" % "1.2.1",
"fr.inria.powerspy" % "powerspy-core_2.11" % "1.2",
"com.nativelibs4java" % "bridj" % "0.7.0",
"com.github.scala-incubator.io" %% "scala-io-core" % "0.4.3",
"com.github.scala-incubator.io" %% "scala-io-file" % "0.4.3",
"org.jfree" % "jfreechart" % "1.0.19",
"org.scala-saddle" %% "saddle-core" % "1.3.3",
"org.scala-saddle" %% "saddle-core" % "1.3.4",
"org.hyperic" % "sigar" % "1.6.5.132",
"io.spray" %% "spray-can" % "1.3.3",
"io.spray" %% "spray-client" % "1.3.3",
"io.spray" %% "spray-routing" % "1.3.3",
"io.spray" %% "spray-json" % "1.3.2",
"com.github.nscala-time" %% "nscala-time" % "2.0.0",
"net.java.dev.jna" % "jna" % "4.1.0",
"com.github.docker-java" % "docker-java" % "2.1.1"
"com.github.nscala-time" %% "nscala-time" % "2.8.0",
"net.java.dev.jna" % "jna" % "4.2.1",
"com.github.docker-java" % "docker-java" % "2.1.4"
)

// Tests
libraryDependencies ++= Seq(
"com.typesafe.akka" %% "akka-testkit" % "2.3.11" % "test",
"com.typesafe.akka" %% "akka-testkit" % "2.3.14" % "test",
"org.scalatest" %% "scalatest" % "2.2.5" % "test",
"org.scalamock" %% "scalamock-scalatest-support" % "3.2.2" % "test",
"io.spray" %% "spray-testkit" % "1.3.3" % "test"
Expand Down Expand Up @@ -75,15 +75,3 @@ publishTo := {
else
Some("releases" at nexus + "service/local/staging/deploy/maven2")
}

val downloadBluecoveLibs = taskKey[Seq[File]]("download-bluecove")

downloadBluecoveLibs := {
val locationBluecove = baseDirectory.value / "lib" / "bluecove-2.1.0.jar"
val locationBluecoveGpl = baseDirectory.value / "lib" / "bluecove-gpl-2.1.0.jar"
if(!locationBluecove.getParentFile.exists()) locationBluecove.getParentFile.mkdirs()
if(!locationBluecoveGpl.getParentFile.exists()) locationBluecoveGpl.getParentFile.mkdirs()
if(!locationBluecove.exists()) IO.download(url("https://bluecove.googlecode.com/files/bluecove-2.1.0.jar"), locationBluecove)
if(!locationBluecoveGpl.exists()) IO.download(url("https://bluecove.googlecode.com/files/bluecove-gpl-2.1.0.jar"), locationBluecoveGpl)
Seq(locationBluecove, locationBluecoveGpl)
}
32 changes: 13 additions & 19 deletions powerapi-core/src/main/scala/org/powerapi/core/OSHelper.scala
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ import com.typesafe.config.Config
import java.io.{IOException, File}
import java.util.UUID
import org.apache.logging.log4j.LogManager
import org.hyperic.sigar.{Sigar, SigarException, SigarProxyCache}
import org.hyperic.sigar.{SigarProxy, Sigar, SigarException, SigarProxyCache}
import org.hyperic.sigar.ptql.ProcessFinder
import org.powerapi.core.FileHelper.using
import org.powerapi.core.target.{All, Application, Container, Process, Target, TargetUsageRatio}
Expand Down Expand Up @@ -402,34 +402,28 @@ class LinuxHelper extends Configuration(None) with OSHelper {
}
}

trait SigarHelperConfiguration extends Configuration {
/**
* Sigar native libraries
*/
lazy val libNativePath = load { _.getString("powerapi.sigar.native-path") } match {
case ConfigValue(p) => p
case _ => "./lib/sigar-bin"
}
}

/**
* SIGAR special helper.
*
* @author <a href="mailto:l.huertas.pro@gmail.com">Loïc Huertas</a>
*/
class SigarHelper extends Configuration(None) with OSHelper {
class SigarHelper(sigar: SigarProxy) extends OSHelper {
private val log = LogManager.getLogger

/**
* Sigar native libraries
*/
lazy val libNativePath = load { _.getString("powerapi.sigar.native-path") } match {
case ConfigValue(p) => p
case _ => "./lib"
}

/**
* SIGAR's proxy instance.
*/
lazy val sigar = {
System.setProperty("java.library.path", libNativePath)
SigarProxyCache.newInstance(new Sigar(), 100)
}

/**
* CPU cores number.
*/
lazy val cores = sigar.getCpuInfoList()(0).getTotalCores()
lazy val cores = sigar.getCpuInfoList()(0).getTotalCores

def getCPUFrequencies: Set[Long] = throw new SigarException("sigar cannot be able to get CPU frequencies")

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,9 @@
*/
package org.powerapi.module.cpu.simple

import org.hyperic.sigar.{Sigar, SigarProxyCache}
import org.powerapi.PowerModule
import org.powerapi.core.{SigarHelper, LinuxHelper, OSHelper}
import org.powerapi.core.{SigarHelperConfiguration, SigarHelper, LinuxHelper, OSHelper}

class CpuSimpleModule(osHelper: OSHelper, tdp: Double, tdpFactor: Double) extends PowerModule {
lazy val underlyingSensorsClasses = Seq((classOf[CpuSensor], Seq(osHelper)))
Expand All @@ -38,9 +39,14 @@ object ProcFSCpuSimpleModule extends CpuFormulaConfiguration {
}
}

object SigarCpuSimpleModule extends CpuFormulaConfiguration {
object SigarCpuSimpleModule extends CpuFormulaConfiguration with SigarHelperConfiguration {
val sigar = {
System.setProperty("java.library.path", libNativePath)
SigarProxyCache.newInstance(new Sigar(), 100)
}

def apply(): CpuSimpleModule = {
val sigarHelper = new SigarHelper
val sigarHelper = new SigarHelper(sigar)

new CpuSimpleModule(sigarHelper, tdp, tdpFactor)
}
Expand Down
38 changes: 38 additions & 0 deletions powerapi-core/src/test/resources/log4j.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!--
~ This software is licensed under the GNU Affero General Public License, quoted below.
~
~ This file is a part of PowerAPI.
~
~ Copyright (C) 2011-2016 Inria, University of Lille 1.
~
~ PowerAPI is free software: you can redistribute it and/or modify
~ it under the terms of the GNU Affero General Public License as
~ published by the Free Software Foundation, either version 3 of
~ the License, or (at your option) any later version.
~
~ PowerAPI is distributed in the hope that it will be useful,
~ but WITHOUT ANY WARRANTY; without even the implied warranty of
~ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
~ GNU Affero General Public License for more details.
~
~ You should have received a copy of the GNU Affero General Public License
~ along with PowerAPI.
~
~ If not, please consult http://www.gnu.org/licenses/agpl-3.0.html.
-->
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">

<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">
<appender name="console" class="org.apache.log4j.ConsoleAppender">
<param name="Target" value="System.out"/>
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="[%level] [%d{MM/dd/yyyy HH:mm:ss.SSS}] [%t] [%logger{36}] - %msg%n"/>
</layout>
</appender>

<root>
<priority value="error" />
<appender-ref ref="console" />
</root>
</log4j:configuration>
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ import java.util.UUID
import akka.actor.ActorSystem
import akka.testkit.TestKit
import akka.util.Timeout
import org.hyperic.sigar.SigarException
import org.hyperic.sigar.{Sigar, SigarProxyCache, SigarException}
import org.powerapi.UnitTest
import org.powerapi.core.target.{All, Application, Container, Process, intToProcess, stringToApplication, TargetUsageRatio}
import org.powerapi.module.CacheKey
Expand Down Expand Up @@ -250,17 +250,19 @@ class OSHelperSuite(system: ActorSystem) extends UnitTest(system) {
(timesLeft - timesRight) should equal(TimeInStates(Map(1l -> 9l, 2l -> 18l, 3l -> 27l, 4l -> 15l)))
}

"The SigarHelper" should "be able to read configuration parameters" in {
val sigarHelper = new SigarHelper
"The SigarHelperConfiguration" should "be able to read configuration parameters" in {
val sigarHelper = new SigarHelperConfiguration {}

sigarHelper.libNativePath should equal("p2")
}

"The SigarHelper methods" should "return correct values" in {
val helper = new SigarHelper {
override lazy val libNativePath = "./powerapi-core/lib"
"The SigarHelper methods" should "return correct values" ignore {
val sigar = {
System.setProperty("java.library.path", s"./../external-libs/sigar-bin")
SigarProxyCache.newInstance(new Sigar(), 100)
}


val helper = new SigarHelper(sigar)
val pid = Process(java.lang.management.ManagementFactory.getRuntimeMXBean.getName.split("@")(0).toInt)

intercept[SigarException] { helper.getCPUFrequencies }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,6 @@ class CpuSimpleModulesSuite(system: ActorSystem) extends UnitTest(system) {
module.underlyingSensorsClasses(0)._1 should equal(classOf[CpuSensor])
module.underlyingSensorsClasses(0)._2.size should equal(1)
module.underlyingSensorsClasses(0)._2(0).getClass should equal(classOf[SigarHelper])
module.underlyingSensorsClasses(0)._2(0).asInstanceOf[SigarHelper].libNativePath should equal("p2")

module.underlyingFormulaeClasses.size should equal(1)
module.underlyingFormulaeClasses(0)._1 should equal(classOf[CpuFormula])
Expand Down
44 changes: 16 additions & 28 deletions powerapi-daemon/build.sbt
Original file line number Diff line number Diff line change
@@ -1,44 +1,32 @@
enablePlugins(JavaServerAppPackaging)

name := "powerapi-daemon"

libraryDependencies ++= Seq(
"commons-daemon" % "commons-daemon" % "1.0.15"
)

lazy val downloadBluecoveDaemon = taskKey[File]("download-bluecove-daemon")
lazy val downloadBluecoveGplDaemon = taskKey[File]("download-bluecove-gpl-daemon")
mappings in Universal += downloadBluecove.value -> s"lib/${downloadBluecove.value.name}"

downloadBluecoveDaemon := {
val locationBluecove = baseDirectory.value / "lib" / "bluecove-2.1.0.jar"
if(!locationBluecove.getParentFile.exists()) locationBluecove.getParentFile.mkdirs()
if(!locationBluecove.exists()) IO.download(url("https://bluecove.googlecode.com/files/bluecove-2.1.0.jar"), locationBluecove)
locationBluecove
}
mappings in Universal += downloadBluecoveGpl.value -> s"lib/${downloadBluecoveGpl.value.name}"

downloadBluecoveGplDaemon := {
val locationBluecoveGpl = baseDirectory.value / "lib" / "bluecove-gpl-2.1.0.jar"
if(!locationBluecoveGpl.getParentFile.exists()) locationBluecoveGpl.getParentFile.mkdirs()
if(!locationBluecoveGpl.exists()) IO.download(url("https://bluecove.googlecode.com/files/bluecove-gpl-2.1.0.jar"), locationBluecoveGpl)
locationBluecoveGpl
mappings in Universal ++= {
val dir = baseDirectory.value.getParentFile

(for {
(file, relativePath) <- (dir * "README*" --- dir) pair relativeTo (dir)
} yield file -> s"$relativePath") ++
(for {
(file, relativePath) <- (dir * "LICENSE*" --- dir) pair relativeTo (dir)
} yield file -> s"$relativePath")
}

mappings in Universal += downloadBluecoveDaemon.value -> s"lib/${downloadBluecoveDaemon.value.name}"

mappings in Universal += downloadBluecoveGplDaemon.value -> s"lib/${downloadBluecoveGplDaemon.value.name}"

mappings in Universal ++= {
((file("../") * "README*").get map {
readmeFile: File =>
readmeFile -> readmeFile.getName
}) ++
((file("../") * "LICENSE*").get map {
licenseFile: File =>
licenseFile -> licenseFile.getName
})
val dir = baseDirectory.value.getParentFile / "external-libs" / "sigar-bin"

for {
(file, relativePath) <- (dir.*** --- dir) pair relativeTo(dir)
} yield file -> s"/lib/sigar-bin/$relativePath"
}

scriptClasspath ++= Seq("../conf", "../scripts")

NativePackagerKeys.executableScriptName := "powerapid"

Loading

0 comments on commit 4a40844

Please sign in to comment.