2323package org .powerapi .app
2424
2525import java .lang .management .ManagementFactory
26- import org .powerapi .core .target ._
27- import org .powerapi .module .rapl .RAPLModule
28- import org .powerapi .reporter .{FileDisplay , JFreeChartDisplay , ConsoleDisplay }
29- import org .powerapi .{PowerDisplay , PowerMonitoring , PowerMeter }
30- import org .powerapi .core .power ._
31- import org .powerapi .module .cpu .dvfs .CpuDvfsModule
32- import org .powerapi .module .cpu .simple .{SigarCpuSimpleModule , ProcFSCpuSimpleModule }
33- import org .powerapi .module .libpfm ._
34- import org .powerapi .module .extPMeter .powerspy .PowerSpyModule
35- import org .powerapi .module .extPMeter .g5k .G5kOmegaWattModule
26+
3627import scala .concurrent .duration .DurationInt
3728import scala .sys
3829import scala .sys .process .stringSeqToProcess
3930import scala .util .matching .Regex
4031
32+ import org .powerapi .core .power ._
33+ import org .powerapi .core .target ._
34+ import org .powerapi .module .cpu .dvfs .CpuDvfsModule
35+ import org .powerapi .module .cpu .simple .{ProcFSCpuSimpleModule , SigarCpuSimpleModule }
36+ import org .powerapi .module .extpowermeter .g5komegawatt .G5kOmegaWattModule
37+ import org .powerapi .module .extpowermeter .powerspy .PowerSpyModule
38+ import org .powerapi .module .extpowermeter .rapl .RAPLModule
39+ import org .powerapi .module .libpfm .{LibpfmCoreModule , LibpfmCoreProcessModule , LibpfmHelper , LibpfmModule , LibpfmProcessModule }
40+ import org .powerapi .reporter .{ConsoleDisplay , FileDisplay , JFreeChartDisplay }
41+ import org .powerapi .{PowerDisplay , PowerMeter , PowerMonitoring }
42+
4143/**
42- * PowerAPI CLI.
43- *
44- * @author <a href="mailto:maxime.colmant@gmail.com">Maxime Colmant</a>
45- * @author <a href="mailto:l.huertas.pro@gmail.com">Loïc Huertas</a>
46- */
44+ * PowerAPI CLI.
45+ *
46+ * @author <a href="mailto:maxime.colmant@gmail.com">Maxime Colmant</a>
47+ * @author <a href="mailto:l.huertas.pro@gmail.com">Loïc Huertas</a>
48+ */
4749object PowerAPI extends App {
4850 val modulesR = """ (procfs-cpu-simple|sigar-cpu-simple|cpu-dvfs|libpfm|libpfm-process|libpfm-core|libpfm-core-process|powerspy|g5k-omegawatt|rapl)(,(procfs-cpu-simple|sigar-cpu-simple|cpu-dvfs|libpfm|libpfm-process|libpfm-core|libpfm-core-process|powerspy|g5k-omegawatt|rapl))*""" .r
4951 val aggR = """ max|min|geomean|logsum|mean|median|stdev|sum|variance""" .r
@@ -107,88 +109,116 @@ object PowerAPI extends App {
107109 }
108110
109111 def cli (options : List [Map [Symbol , Any ]], duration : String , args : List [String ]): (List [Map [Symbol , Any ]], String ) = args match {
110- case Nil => (options, duration)
111- case " modules" :: value :: " --prefix" :: prefix :: " monitor" :: tail if validate(modulesR, value) => {
112+ case Nil =>
113+ (options, duration)
114+ case " modules" :: value :: " --prefix" :: prefix :: " monitor" :: tail if validate(modulesR, value) =>
112115 val (remainingArgs, monitors) = cliMonitorsSubcommand(List (), Map (), tail.map(_.toString))
113116 cli(options :+ Map (' modules -> value, ' prefix -> Some (prefix), ' monitors -> monitors), duration, remainingArgs)
114- }
115- case " modules" :: value :: " monitor" :: tail if validate(modulesR, value) => {
117+ case " modules" :: value :: " monitor" :: tail if validate(modulesR, value) =>
116118 val (remainingArgs, monitors) = cliMonitorsSubcommand(List (), Map (), tail.map(_.toString))
117119 cli(options :+ Map (' modules -> value, ' prefix -> None , ' monitors -> monitors), duration, remainingArgs)
118- }
119- case " duration" :: value :: tail if validate(durationR, value) => cli(options, value, tail)
120- case option :: tail => println(s " unknown cli option $option" ); sys.exit(1 )
120+ case " duration" :: value :: tail if validate(durationR, value) =>
121+ cli(options, value, tail)
122+ case option :: tail =>
123+ println(s " unknown cli option $option" )
124+ sys.exit(1 )
121125 }
122126
123127 def cliMonitorsSubcommand (options : List [Map [Symbol , Any ]], currentMonitor : Map [Symbol , Any ], args : List [String ]): (List [String ], List [Map [Symbol , Any ]]) = args match {
124- case Nil => (List (), options :+ currentMonitor)
125- case " modules" :: value :: " --prefix" :: prefix :: " monitor" :: tail if validate(modulesR, value) => (List (" modules" , value, " --prefix" , prefix, " monitor" ) ++ tail, options :+ currentMonitor)
126- case " modules" :: value :: " monitor" :: tail if validate(modulesR, value) => (List (" modules" , value, " monitor" ) ++ tail, options :+ currentMonitor)
127- case " duration" :: value :: tail if validate(durationR, value) => (List (" duration" , value) ++ tail, options :+ currentMonitor)
128- case " monitor" :: tail => cliMonitorsSubcommand(options :+ currentMonitor, Map (), tail)
129- case " --frequency" :: value :: tail if validate(durationR, value) => cliMonitorsSubcommand(options, currentMonitor ++ Map (' frequency -> value), tail)
130- case " --self" :: tail => cliMonitorsSubcommand(options, currentMonitor + (' targets -> (currentMonitor.getOrElse(' targets , Set [Any ]()).asInstanceOf [Set [Any ]] + Process (ManagementFactory .getRuntimeMXBean.getName.split(" @" )(0 ).toInt))), tail)
131- case " --pids" :: value :: tail if validate(pidsR, value) => cliMonitorsSubcommand(options, currentMonitor + (' targets -> (currentMonitor.getOrElse(' targets , Set [Any ]()).asInstanceOf [Set [Any ]] ++ value.split(" ," ).map(pid => Process (pid.toInt)))), tail)
132- case " --apps" :: value :: tail if validate(appsR, value) => cliMonitorsSubcommand(options, currentMonitor + (' targets -> (currentMonitor.getOrElse(' targets , Set [Any ]()).asInstanceOf [Set [Any ]] ++ value.split(" ," ).map(app => Application (app)))), tail)
133- case " --containers" :: value :: tail if validate(containersR, value) => cliMonitorsSubcommand(options, currentMonitor + (' targets -> (currentMonitor.getOrElse(' targets , Set [Any ]()).asInstanceOf [Set [Any ]] ++ value.split(" ," ).map(container => Container (container)))), tail)
134- case " --all" :: tail => cliMonitorsSubcommand(options, currentMonitor + (' targets -> (currentMonitor.getOrElse(' targets , Set [Any ]()).asInstanceOf [Set [Any ]] + All )), tail)
135- case " --agg" :: value :: tail if validate(aggR, value) => cliMonitorsSubcommand(options, currentMonitor ++ Map (' agg -> value), tail)
136- case " --console" :: tail => cliMonitorsSubcommand(options, currentMonitor + (' displays -> (currentMonitor.getOrElse(' displays , Set [Any ]()).asInstanceOf [Set [Any ]] + new ConsoleDisplay )), tail)
137- case " --file" :: value :: tail => cliMonitorsSubcommand(options, currentMonitor + (' displays -> (currentMonitor.getOrElse(' displays , Set [Any ]()).asInstanceOf [Set [Any ]] + new FileDisplay (value))), tail)
138- case " --chart" :: tail => cliMonitorsSubcommand(options, currentMonitor + (' displays -> (currentMonitor.getOrElse(' displays , Set [Any ]()).asInstanceOf [Set [Any ]] + new JFreeChartDisplay )), tail)
139- case option :: tail => println(s " unknown monitor option $option" ); sys.exit(1 )
128+ case Nil =>
129+ (List (), options :+ currentMonitor)
130+ case " modules" :: value :: " --prefix" :: prefix :: " monitor" :: tail if validate(modulesR, value) =>
131+ (List (" modules" , value, " --prefix" , prefix, " monitor" ) ++ tail, options :+ currentMonitor)
132+ case " modules" :: value :: " monitor" :: tail if validate(modulesR, value) =>
133+ (List (" modules" , value, " monitor" ) ++ tail, options :+ currentMonitor)
134+ case " duration" :: value :: tail if validate(durationR, value) =>
135+ (List (" duration" , value) ++ tail, options :+ currentMonitor)
136+ case " monitor" :: tail =>
137+ cliMonitorsSubcommand(options :+ currentMonitor, Map (), tail)
138+ case " --frequency" :: value :: tail if validate(durationR, value) =>
139+ cliMonitorsSubcommand(options, currentMonitor ++ Map (' frequency -> value), tail)
140+ case " --self" :: tail =>
141+ cliMonitorsSubcommand(options, currentMonitor + (' targets -> (currentMonitor.getOrElse(' targets , Set [Any ]()).asInstanceOf [Set [Any ]] + Process (ManagementFactory .getRuntimeMXBean.getName.split(" @" )(0 ).toInt))), tail)
142+ case " --pids" :: value :: tail if validate(pidsR, value) =>
143+ cliMonitorsSubcommand(options, currentMonitor + (' targets -> (currentMonitor.getOrElse(' targets , Set [Any ]()).asInstanceOf [Set [Any ]] ++ value.split(" ," ).map(pid => Process (pid.toInt)))), tail)
144+ case " --apps" :: value :: tail if validate(appsR, value) =>
145+ cliMonitorsSubcommand(options, currentMonitor + (' targets -> (currentMonitor.getOrElse(' targets , Set [Any ]()).asInstanceOf [Set [Any ]] ++ value.split(" ," ).map(app => Application (app)))), tail)
146+ case " --containers" :: value :: tail if validate(containersR, value) =>
147+ cliMonitorsSubcommand(options, currentMonitor + (' targets -> (currentMonitor.getOrElse(' targets , Set [Any ]()).asInstanceOf [Set [Any ]] ++ value.split(" ," ).map(container => Container (container)))), tail)
148+ case " --all" :: tail =>
149+ cliMonitorsSubcommand(options, currentMonitor + (' targets -> (currentMonitor.getOrElse(' targets , Set [Any ]()).asInstanceOf [Set [Any ]] + All )), tail)
150+ case " --agg" :: value :: tail if validate(aggR, value) =>
151+ cliMonitorsSubcommand(options, currentMonitor ++ Map (' agg -> value), tail)
152+ case " --console" :: tail =>
153+ cliMonitorsSubcommand(options, currentMonitor + (' displays -> (currentMonitor.getOrElse(' displays , Set [Any ]()).asInstanceOf [Set [Any ]] + new ConsoleDisplay )), tail)
154+ case " --file" :: value :: tail =>
155+ cliMonitorsSubcommand(options, currentMonitor + (' displays -> (currentMonitor.getOrElse(' displays , Set [Any ]()).asInstanceOf [Set [Any ]] + new FileDisplay (value))), tail)
156+ case " --chart" :: tail =>
157+ cliMonitorsSubcommand(options, currentMonitor + (' displays -> (currentMonitor.getOrElse(' displays , Set [Any ]()).asInstanceOf [Set [Any ]] + new JFreeChartDisplay )), tail)
158+ case option :: tail =>
159+ println(s " unknown monitor option $option" )
160+ sys.exit(1 )
140161 }
141162
142- if (args.size == 0 ) {
163+ if (args.isEmpty ) {
143164 printHelp()
144165 sys.exit(1 )
145166 }
146167
147168 else {
148- if (System .getProperty(" os.name" ).toLowerCase.indexOf(" nix" ) >= 0 || System .getProperty(" os.name" ).toLowerCase.indexOf(" nux" ) >= 0 ) Seq (" bash" , " scripts/system.bash" ).!
149- System .setProperty(" java.library.path" , " lib" )
169+ if (System .getProperty(" os.name" ).toLowerCase.indexOf(" nix" ) >= 0 || System .getProperty(" os.name" ).toLowerCase.indexOf(" nux" ) >= 0 ) Seq (" bash" , " scripts/system.bash" ).!
150170
151171 val (configuration, duration) = cli(List (), " 3600" , args.toList)
152172
153173 var libpfmHelper : Option [LibpfmHelper ] = None
154174
155- if (configuration.count(powerMeterConf => powerMeterConf(' modules ).toString.contains(" libpfm" )) != 0 ) {
175+ if (configuration.count(powerMeterConf => powerMeterConf(' modules ).toString.contains(" libpfm" )) != 0 ) {
156176 libpfmHelper = Some (new LibpfmHelper )
157177 libpfmHelper.get.init()
158178 }
159179
160- for (powerMeterConf <- configuration) {
161- val modules = (for (module <- powerMeterConf(' modules ).toString.split(" ," )) yield {
180+ for (powerMeterConf <- configuration) {
181+ val modules = (for (module <- powerMeterConf(' modules ).toString.split(" ," )) yield {
162182 module match {
163- case " procfs-cpu-simple" => ProcFSCpuSimpleModule ()
164- case " sigar-cpu-simple" => SigarCpuSimpleModule ()
165- case " cpu-dvfs" => CpuDvfsModule ()
166- case " libpfm" => LibpfmModule (powerMeterConf(' prefix ).asInstanceOf [Option [String ]], libpfmHelper.get)
167- case " libpfm-process" => LibpfmProcessModule (powerMeterConf(' prefix ).asInstanceOf [Option [String ]], libpfmHelper.get)
168- case " libpfm-core" => LibpfmCoreModule (powerMeterConf(' prefix ).asInstanceOf [Option [String ]], libpfmHelper.get)
169- case " libpfm-core-process" => LibpfmCoreProcessModule (powerMeterConf(' prefix ).asInstanceOf [Option [String ]], libpfmHelper.get)
170- case " powerspy" => PowerSpyModule (powerMeterConf(' prefix ).asInstanceOf [Option [String ]])
171- case " g5k-omegawatt" => G5kOmegaWattModule (powerMeterConf(' prefix ).asInstanceOf [Option [String ]])
172- case " rapl" => RAPLModule ()
183+ case " procfs-cpu-simple" =>
184+ ProcFSCpuSimpleModule ()
185+ case " sigar-cpu-simple" =>
186+ SigarCpuSimpleModule ()
187+ case " cpu-dvfs" =>
188+ CpuDvfsModule ()
189+ case " libpfm" =>
190+ LibpfmModule (powerMeterConf(' prefix ).asInstanceOf [Option [String ]], libpfmHelper.get)
191+ case " libpfm-process" =>
192+ LibpfmProcessModule (powerMeterConf(' prefix ).asInstanceOf [Option [String ]], libpfmHelper.get)
193+ case " libpfm-core" =>
194+ LibpfmCoreModule (powerMeterConf(' prefix ).asInstanceOf [Option [String ]], libpfmHelper.get)
195+ case " libpfm-core-process" =>
196+ LibpfmCoreProcessModule (powerMeterConf(' prefix ).asInstanceOf [Option [String ]], libpfmHelper.get)
197+ case " powerspy" =>
198+ PowerSpyModule (powerMeterConf(' prefix ).asInstanceOf [Option [String ]])
199+ case " g5k-omegawatt" =>
200+ G5kOmegaWattModule (powerMeterConf(' prefix ).asInstanceOf [Option [String ]])
201+ case " rapl" =>
202+ RAPLModule ()
173203 }
174204 }).toSeq
175205
176206 val powerMeter = PowerMeter .loadModule(modules : _* )
177207 powerMeters :+= powerMeter
178208
179- for (monitorConf <- powerMeterConf(' monitors ).asInstanceOf [List [Map [Symbol , Any ]]]) {
209+ for (monitorConf <- powerMeterConf(' monitors ).asInstanceOf [List [Map [Symbol , Any ]]]) {
180210 val frequency = monitorConf.getOrElse(' frequency , " 1000" ).toString.toInt.milliseconds
181211 val targets = {
182212 val uniqueTargets = monitorConf.getOrElse(' targets , Set (Process (ManagementFactory .getRuntimeMXBean.getName.split(" @" )(0 ).toInt))).asInstanceOf [Set [Target ]].toSeq
183- if (uniqueTargets.contains(All )) Seq (All ) else uniqueTargets
213+ if (uniqueTargets.contains(All )) Seq (All ) else uniqueTargets
184214 }
185215 val agg : Seq [Power ] => Power = aggStrToAggFunction(monitorConf.getOrElse(' agg , " max" ).toString.toLowerCase)
186216 val displays = monitorConf.getOrElse(' displays , Set (new ConsoleDisplay )).asInstanceOf [Set [PowerDisplay ]]
187217
188- val monitor = powerMeter.monitor(frequency)( targets : _* )(agg)
218+ val monitor = powerMeter.monitor(targets : _* )(agg).every(frequency )
189219 monitors :+= monitor
190220
191- for (display <- displays) {
221+ for (display <- displays) {
192222 monitor.to(display)
193223 }
194224 }
@@ -198,7 +228,7 @@ object PowerAPI extends App {
198228
199229 libpfmHelper match {
200230 case Some (helper) => helper.deinit()
201- case _ => {}
231+ case _ =>
202232 }
203233 }
204234
0 commit comments