From 2e3b66a22f0d0bf9dd68cedf22944c6ba38326d9 Mon Sep 17 00:00:00 2001 From: Ziver Koc Date: Tue, 19 May 2015 15:52:00 +0000 Subject: [PATCH] --- resources/WebContent/img/error.png | Bin 0 -> 3617 bytes resources/WebContent/img/hdd.png | Bin 0 -> 1749 bytes resources/WebContent/img/hdd_fail.png | Bin 0 -> 3920 bytes resources/WebContent/img/hdd_ok.png | Bin 0 -> 3675 bytes resources/WebContent/img/hdd_warn.png | Bin 0 -> 10979 bytes src/wa/server/page/ServicePage.tmpl | 133 +++++++++++ src/wa/server/page/ServicesPage.java | 31 +++ src/wa/server/plugin/WAService.java | 17 +- src/wa/server/plugin/WAServiceStatus.java | 36 +++ .../server/plugin/apache/ApacheInstaller.java | 5 +- .../server/plugin/apache/ApacheService.java | 37 ++- src/wa/server/plugin/apache/ApacheStatus.java | 64 ++++++ src/wa/server/plugin/apache/plugin.json | 2 - src/wa/server/util/ProcDiskstats.java | 215 ++++++++++++++++++ src/wa/server/util/ProcStat.java | 193 ++++++++++++++++ 15 files changed, 699 insertions(+), 34 deletions(-) create mode 100644 resources/WebContent/img/error.png create mode 100644 resources/WebContent/img/hdd.png create mode 100644 resources/WebContent/img/hdd_fail.png create mode 100644 resources/WebContent/img/hdd_ok.png create mode 100644 resources/WebContent/img/hdd_warn.png create mode 100644 src/wa/server/page/ServicePage.tmpl create mode 100644 src/wa/server/plugin/WAServiceStatus.java create mode 100644 src/wa/server/plugin/apache/ApacheStatus.java create mode 100644 src/wa/server/util/ProcDiskstats.java create mode 100644 src/wa/server/util/ProcStat.java diff --git a/resources/WebContent/img/error.png b/resources/WebContent/img/error.png new file mode 100644 index 0000000000000000000000000000000000000000..56c94f17f11b2ef81f766d69124378d6af1a666a GIT binary patch literal 3617 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 literal 0 HcmV?d00001 diff --git a/resources/WebContent/img/hdd.png b/resources/WebContent/img/hdd.png new file mode 100644 index 0000000000000000000000000000000000000000..0fa45949c5b279bcf561a8dec89efcecdde576be GIT binary patch literal 1749 zcmV;`1}gc9P)S&0}{gMdGrv+OF=N z-u`{>`l?n5|DTWM0DJ&G0DnxMWb{|hF1D94K|u9=qsF^3_4Y5Wk9xZrRY0Ekk-R*+ zkV^RduxDlDwbI*nc7JT73c&<1knMMFwLf_6d(7K=rk2*&BGNl4vuAmkKm^I4`YUi!qo;EVT8KlORK z6eui~gcO7FFt84;FkW-<0fiG(ks&BrJjjWu?JN6&+h1F5eu`UV=^;gXr1iRr^I(aV zD4wgM#-M=?nscPrUe$Yof1qn?7l1n`5)y~1j+M@#uGX7BOsJ}a7=#vQSy=tc`8~mZ zI(vBaJS~J26L`~lU3=*h8`%1D32dM-v^l~G#Y=mF^KY%P$R-BueMz5zwez|3q2psU zVQ4HnoTqX5s|zE+R}M9weVmL89eK418tptMfqp$>ht)jHY)y+5?pcPuwHIacU2Mp6SEI5V^6P(6;dnDMrc#a9S(HM$ATjgSyNY~h>GGcy)8qnq( zv**6JIu!hc6LU{opp9Tj(Bv+Hb%2#9rTPsVV-*TZ4G`KKl#R2fUk1ee{%7&ME3&jjIZ&-;cSM1kHIDFF}2u)_`&~{>Um|_+E zodK}9_6T#d{R;|i(Pfe;43;9m5n+36LeDl(XP!y6*hIO6v)tw^haUgR$q4-P?4e7a zqfPEpNnvTRiDHHs>MnbWAg@Dcna>tTnPh<(a@L);f+hjBInIe%=YPjM5& zG_y3l1|2?P6U!9y%rQmXPk{uQD-1Q7OtZi|O?LS&A35I&3G>V|LyqMvwQqjC8T4Ee zm(QTNL!AWWZdQSGn>(aTFhPS!7gB{YxpGrMi74o@Lzf&u`@dIcr(v5%`1OhRALBO; z{0iv<_p^hgOAAd#5fwe5O9zD}A;Gv_tkOB7pdcqF3sTE^;k#_0$q+gm=N{fW>A@dN z&`7B{eT0c=6yWYD z#0BAy*{Ld!T{?8xB_}7RaM_ESmHVHr!f=WP1+xeZnh0|gOwzz|4~ctD`j;?a$;){c zOU*}cnPA$dg&OL|f?0AlIK_u7qPfW_{=-pnHd*2}dBg}bwtKYNDw=PHhfp|oRcB$3 zLJ&Qkq6Lv)&7k`*{a5>M%E?|CAs$>PRQOnfBny9{C()9%AG*ISEMOCWL>c7%+ELZ>iDr>5DVm%P9df6=9=awRw1f=Yi|d>< zpmc&k3KN=InDK3oa-}~bC!-(_CdIfXsaksLI}_{Mq9PX20470T*P<+m_v(jz4Ng^1 z?2uNV7YFNDYW$0oTPSM$gE}{Xl)sbv92U0-O~}z7Y<&90JI5a-bxm#Dw2EINhDV9g z#`<6^m~&@2v#y2}4x4g=7W@^+6A@Ji7hnJV&$jraU;9bl28(!eGN9|A73|QG3K`ew z{#5=5(%bd9^wiE;a#9%p@w*FBMpXHf3gScsK_kHyl5@HecLh?8N|dr&`d4#ryww@G z-K6ll4&}PVL_00G>KXSxRWudu*HV;)UW&Wg*;5SJ*opUC`s-!s`XXM*%iV4%GHm}c rH1x1?CNTE<4*nT(06qYJT%Z2|vKFt(ayrMc00000NkvXXu0mjfOpicY literal 0 HcmV?d00001 diff --git a/resources/WebContent/img/hdd_fail.png b/resources/WebContent/img/hdd_fail.png new file mode 100644 index 0000000000000000000000000000000000000000..02f0170278cf51009bb593fa86f0b2f6900e6185 GIT binary patch literal 3920 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 literal 0 HcmV?d00001 diff --git a/resources/WebContent/img/hdd_warn.png b/resources/WebContent/img/hdd_warn.png new file mode 100644 index 0000000000000000000000000000000000000000..e1d1e4d075c01393d563577d531c62a8775bdacc GIT binary patch literal 10979 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
+
Cpu Status
+
+
+
+
+
+
Memory
+
+
+
+ + + + + + +
UsedFree
Memory
Swap
+
+
+
+
Process List
+
+ + + + + + + + + + + +
PIDUserCPUCpuTimeMemory(MB)Proc
+
+
+ + diff --git a/src/wa/server/page/ServicesPage.java b/src/wa/server/page/ServicesPage.java index 27c7d21..17bea8f 100644 --- a/src/wa/server/page/ServicesPage.java +++ b/src/wa/server/page/ServicesPage.java @@ -26,18 +26,26 @@ import wa.server.WAAbstractPage; import wa.server.WAContext; import wa.server.page.struct.WANavigation; import wa.server.plugin.WAService; +import zutil.io.file.FileUtil; +import zutil.log.LogUtil; import zutil.net.http.HttpHeaderParser; import zutil.parser.DataNode; import zutil.parser.Templator; import zutil.plugin.PluginManager; +import java.io.IOException; import java.util.ArrayList; import java.util.Map; +import java.util.logging.Level; +import java.util.logging.Logger; /** * Created by Ziver on 2015-04-06. */ public class ServicesPage implements WAPage { + private static final Logger log = LogUtil.getLogger(); + private static final String TMPL_FILE = ""; + private ArrayList plugins; public ServicesPage(PluginManager pluginManager){ @@ -56,6 +64,18 @@ public class ServicesPage implements WAPage { Map session, Map cookie, Map request) { + + try { + WAService obj = getPlugin(context); + + if (obj != null) { + Templator tmpl = new Templator(FileUtil.find(TMPL_FILE)); + tmpl.set("nav", context.getBreadcrumb().get(1)); + return tmpl; + } + }catch (IOException e){ + log.log(Level.SEVERE, null, e); + } return null; } @@ -64,6 +84,17 @@ public class ServicesPage implements WAPage { Map session, Map cookie, Map request){ + + return null; + } + + + private WAService getPlugin(WAContext context){ + if(context.getBreadcrumb().size() >= 2){ + int i = plugins.indexOf(context.getBreadcrumb().get(1).getResource()); + if(i >= 0) + return plugins.get(i); + } return null; } diff --git a/src/wa/server/plugin/WAService.java b/src/wa/server/plugin/WAService.java index a29c24b..a189f12 100644 --- a/src/wa/server/plugin/WAService.java +++ b/src/wa/server/plugin/WAService.java @@ -1,15 +1,16 @@ package wa.server.plugin; public interface WAService { - public enum WAServiceStatus{ - RUNNING, - NOT_RESPONDING, - UNAVAILABLE, - UNKNOWN - } public String getName(); - public void start(); - public void stop(); + + /** + * @return a service status object or null if it is not possible to check status + */ public WAServiceStatus getStatus(); + + /** + * @return a installer object that will install the service or null if the installer is not available + */ + public WAInstaller getInstaller(); } diff --git a/src/wa/server/plugin/WAServiceStatus.java b/src/wa/server/plugin/WAServiceStatus.java new file mode 100644 index 0000000..27031e5 --- /dev/null +++ b/src/wa/server/plugin/WAServiceStatus.java @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2015 Ziver + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +package wa.server.plugin; + +public interface WAServiceStatus { + public enum ServiceStatusType{ + RUNNING, + NOT_RESPONDING, + UNAVAILABLE, + UNKNOWN + } + + public void start(); + public void stop(); + public ServiceStatusType getStatus(); +} diff --git a/src/wa/server/plugin/apache/ApacheInstaller.java b/src/wa/server/plugin/apache/ApacheInstaller.java index 64ffb74..431a131 100644 --- a/src/wa/server/plugin/apache/ApacheInstaller.java +++ b/src/wa/server/plugin/apache/ApacheInstaller.java @@ -30,14 +30,15 @@ import zutil.osal.OSAbstractionLayer; * Created by Ziver on 2014-11-09. */ public class ApacheInstaller implements WAInstaller { + private static final String PACKAGES = "apache php5 php5-mcrypt php5-gd imagemagick"; @Override public void install() { - AptGet.install("apache php5 php5-mcrypt php5-gd imagemagick"); + AptGet.install(PACKAGES); } @Override public void uninstall() { - AptGet.purge("apache php5 php5-mcrypt php5-gd imagemagick"); + AptGet.purge(PACKAGES); } } diff --git a/src/wa/server/plugin/apache/ApacheService.java b/src/wa/server/plugin/apache/ApacheService.java index 3982ca5..a8ac665 100644 --- a/src/wa/server/plugin/apache/ApacheService.java +++ b/src/wa/server/plugin/apache/ApacheService.java @@ -22,7 +22,10 @@ package wa.server.plugin.apache; +import wa.server.plugin.WAInstaller; import wa.server.plugin.WAService; +import wa.server.plugin.WAServiceStatus; +import wa.server.util.AptGet; import wa.server.util.Ps; import zutil.io.file.FileUtil; import zutil.log.LogUtil; @@ -39,35 +42,25 @@ import java.util.logging.Logger; public class ApacheService implements WAService { private static Logger log = LogUtil.getLogger(); - private static OSAbstractionLayer os = OSAbstractionLayer.getInstance(); - private static final String PID_FILE = "/var/run/apache2.pid"; + private ApacheStatus status; + private ApacheInstaller installer; @Override public String getName() { return "Apache2"; } - @Override - public void start() { - os.runCommand("service apache2 start"); - } - - @Override - public void stop() { - os.runCommand("service apache2 stop"); - } - @Override public WAServiceStatus getStatus() { - try { - int pid = Integer.parseInt( - FileUtil.getContent(new File(PID_FILE))); - if(Ps.isRunning(pid)) - return WAServiceStatus.RUNNING; - return WAServiceStatus.UNAVAILABLE; - }catch(IOException e){ - log.log(Level.WARNING, null, e); - } - return WAServiceStatus.UNKNOWN; + if(status == null) + status = new ApacheStatus(); + return status; + } + + @Override + public WAInstaller getInstaller() { + if(installer == null) + installer = new ApacheInstaller(); + return installer; } } diff --git a/src/wa/server/plugin/apache/ApacheStatus.java b/src/wa/server/plugin/apache/ApacheStatus.java new file mode 100644 index 0000000..abd8b23 --- /dev/null +++ b/src/wa/server/plugin/apache/ApacheStatus.java @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2015 Ziver + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +package wa.server.plugin.apache; + +import wa.server.plugin.WAServiceStatus; +import wa.server.util.Ps; +import zutil.io.file.FileUtil; +import zutil.log.LogUtil; +import zutil.osal.OSAbstractionLayer; + +import java.io.File; +import java.io.IOException; +import java.util.logging.Level; +import java.util.logging.Logger; + +public class ApacheStatus implements WAServiceStatus { + private static final Logger log = LogUtil.getLogger(); + private static OSAbstractionLayer os = OSAbstractionLayer.getInstance(); + private static final String PID_FILE = "/var/run/apache2.pid"; + + @Override + public void start() { + os.runCommand("service apache2 start"); + } + + @Override + public void stop() { + os.runCommand("service apache2 stop"); + } + + @Override + public ServiceStatusType getStatus() { + try { + int pid = Integer.parseInt( + FileUtil.getContent(new File(PID_FILE))); + if(Ps.isRunning(pid)) + return ServiceStatusType.RUNNING; + return ServiceStatusType.UNAVAILABLE; + }catch(IOException e){ + log.log(Level.WARNING, null, e); + } + return ServiceStatusType.UNKNOWN; + } +} \ No newline at end of file diff --git a/src/wa/server/plugin/apache/plugin.json b/src/wa/server/plugin/apache/plugin.json index f1184b2..8829ba4 100644 --- a/src/wa/server/plugin/apache/plugin.json +++ b/src/wa/server/plugin/apache/plugin.json @@ -2,8 +2,6 @@ "version": "1.0", "name": "Apache Web Server", "interfaces": { - "wa.server.plugin.WAInstaller": "wa.server.plugin.apache.ApacheInstaller", - "wa.server.plugin.WAConfigurator": "wa.server.plugin.apache.ApacheConfigurator", "wa.server.plugin.WAService": "wa.server.plugin.apache.ApacheService" } } \ No newline at end of file diff --git a/src/wa/server/util/ProcDiskstats.java b/src/wa/server/util/ProcDiskstats.java new file mode 100644 index 0000000..b5f96df --- /dev/null +++ b/src/wa/server/util/ProcDiskstats.java @@ -0,0 +1,215 @@ +/* + * Copyright (c) 2015 ezivkoc + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +package wa.server.util; + +import zutil.log.LogUtil; + +import java.io.*; +import java.util.HashMap; +import java.util.logging.Level; +import java.util.logging.Logger; + +/** + * Documentation from https://www.kernel.org/doc/Documentation/block/stat.txt + * + * Created by ezivkoc on 2015-05-19. + */ +public class ProcDiskstats { + private static final Logger log = LogUtil.getLogger(); + private static final String PROC_PATH = "/proc/diskstats"; + private static final int TTL = 500; // update stats every 0.5 second + + private static HashMap hdds = new HashMap(); + private static long updateTimestamp; + + + private synchronized static void update(){ + if(System.currentTimeMillis() - updateTimestamp < TTL) + return; + updateTimestamp = System.currentTimeMillis(); + try { + BufferedReader in = new BufferedReader(new FileReader(PROC_PATH)); + String line = null; + while((line=in.readLine()) != null){ + String[] str = line.split("\\w*", 4); + if(str.length >= 4) { + String devName = str[2]; + if(!hdds.containsKey(devName)){ + HddStats hdd = new HddStats(devName); + hdds.put(hdd.getDevName(), hdd); + } + hdds.get(devName).update(str[3]); + } + } + in.close(); + } catch (IOException e) { + log.log(Level.SEVERE, null, e); + } + } + + public static HddStats getStats(String devName){ + update(); + return hdds.get(devName); + } + + + public static class HddStats { + private String devName; + //read I/Os requests number of read I/Os processed + private long readIO = -1; + //read merges requests number of read I/Os merged with in-queue I/O + private long readMerges = -1; + //read sectors sectors number of sectors read + private long readSectors = -1; + //read ticks milliseconds total wait time for read requests + private long readTicks = -1; + //write I/Os requests number of write I/Os processed + private long writeIO = -1; + //write merges requests number of write I/Os merged with in-queue I/O + private long writeMerges = -1; + //write sectors sectors number of sectors written + private long writeSectors = -1; + //write ticks milliseconds total wait time for write requests + private long writeTicks = -1; + //in_flight requests number of I/Os currently in flight + private long inFlight = -1; + //io_ticks milliseconds total time this block device has been active + private long ioTicks = -1; + //time_in_queue milliseconds total wait time for all requests + private long timeInQueue = -1; + + protected HddStats(String devName) { + this.devName = devName; + } + protected void update(String line){ + String[] stats = line.split("\\w*"); + if(stats.length >= 11){ + readIO = Long.parseLong(stats[0]); + readMerges = Long.parseLong(stats[1]); + readSectors = Long.parseLong(stats[2]); + readTicks = Long.parseLong(stats[3]); + writeIO = Long.parseLong(stats[4]); + writeMerges = Long.parseLong(stats[5]); + writeSectors = Long.parseLong(stats[6]); + writeTicks = Long.parseLong(stats[7]); + inFlight = Long.parseLong(stats[8]); + ioTicks = Long.parseLong(stats[9]); + timeInQueue = Long.parseLong(stats[10]); + } + } + + + public String getDevName() { + return devName; + } + /** + * This values increment when an I/O request completes. + */ + public long getReadIO() { + return readIO; + } + /** + * This value increment when an I/O request is merged with an + * already-queued I/O request. + */ + public long getReadMerges() { + return readMerges; + } + /** + * This value count the number of sectors read from to this + * block device. The "sectors" in question are the standard UNIX 512-byte + * sectors, not any device- or filesystem-specific block size. The + * counter is incremented when the I/O completes. + */ + public long getReadSectors() { + return readSectors; + } + /** + * This value count the number of milliseconds that I/O requests have + * waited on this block device. If there are multiple I/O requests waiting, + * this value will increase at a rate greater than 1000/second; for + * example, if 60 read requests wait for an average of 30 ms, the read_ticks + * field will increase by 60*30 = 1800. + */ + public long getReadTicks() { + return readTicks; + } + /** + * This values increment when an I/O request completes. + */ + public long getWriteIO() { + return writeIO; + } + /** + * This value increment when an I/O request is merged with an + * already-queued I/O request. + */ + public long getWriteMerges() { + return writeMerges; + } + /** + * This value count the number of sectors written to this + * block device. The "sectors" in question are the standard UNIX 512-byte + * sectors, not any device- or filesystem-specific block size. The + * counter is incremented when the I/O completes. + */ + public long getWriteSectors() { + return writeSectors; + } + /** + * This value count the number of milliseconds that I/O requests have + * waited on this block device. If there are multiple I/O requests waiting, + * this value will increase at a rate greater than 1000/second; for + * example, if 60 write requests wait for an average of 30 ms, the write_ticks + * field will increase by 60*30 = 1800. + */ + public long getWriteTicks() { + return writeTicks; + } + /** + * This value counts the number of I/O requests that have been issued to + * the device driver but have not yet completed. It does not include I/O + * requests that are in the queue but not yet issued to the device driver. + */ + public long getInFlight() { + return inFlight; + } + /** + * This value counts the number of milliseconds during which the device has + * had I/O requests queued. + */ + public long getIoTicks() { + return ioTicks; + } + /** + * This value counts the number of milliseconds that I/O requests have waited + * on this block device. If there are multiple I/O requests waiting, this + * value will increase as the product of the number of milliseconds times the + * number of requests waiting (see "read ticks" above for an example). + */ + public long getTimeInQueue() { + return timeInQueue; + } + } + +} diff --git a/src/wa/server/util/ProcStat.java b/src/wa/server/util/ProcStat.java new file mode 100644 index 0000000..7e8a98e --- /dev/null +++ b/src/wa/server/util/ProcStat.java @@ -0,0 +1,193 @@ +/* + * Copyright (c) 2015 ezivkoc + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +package wa.server.util; + +import zutil.log.LogUtil; + +import java.io.BufferedReader; +import java.io.FileReader; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.logging.Level; +import java.util.logging.Logger; + +/** + * Documentation from https://www.kernel.org/doc/Documentation/block/stat.txt + * + * Created by ezivkoc on 2015-05-19. + */ +public class ProcStat { + private static final Logger log = LogUtil.getLogger(); + private static final String PROC_PATH = "/proc/stat"; + private static final int TTL = 500; // update stats every 0.5 second + + private static CpuStats cpuTotal = new CpuStats(); + private static ArrayList cpus = new ArrayList(); + private static long uptime; + private static long processes; + private static long updateTimestamp; + + + private synchronized static void update(){ + if(System.currentTimeMillis() - updateTimestamp < TTL) + return; + updateTimestamp = System.currentTimeMillis(); + try { + BufferedReader in = new BufferedReader(new FileReader(PROC_PATH)); + String line = null; + while((line=in.readLine()) != null){ + String[] str = line.split("\\w*"); + if(str[0].equals("cpu")) + cpuTotal.update(str); + else if(str[0].startsWith("cpu")){ + int cpuId = Integer.parseInt(str[0].substring(3)); + if(cpus.size() < cpuId) + cpus.add(new CpuStats()); + cpus.get(cpuId).update(str); + } + else if(str[0].startsWith("btime")){ + uptime = Long.parseLong(str[1]); + } + else if(str[0].startsWith("processes")){ + processes = Long.parseLong(str[1]); + } + } + in.close(); + } catch (IOException e) { + log.log(Level.SEVERE, null, e); + } + } + + public static CpuStats getTotalCpuStats(){ + update(); + return cpuTotal; + } + public static Iterator getCpuStats(){ + update(); + return cpus.iterator(); + } + /** + * @return the time at which the system booted, in seconds since the Unix epoch. + */ + public static long getUptime(){ + update(); + return uptime; + } + /** + * @return the number of processes and threads created, which includes (but is not limited to) those created by calls to the fork() and clone() system calls. + */ + public static long getProcesses(){ + update(); + return processes; + } + + + + public static class CpuStats { + // normal processes executing in user mode + private long user; + // processes executing in kernel mode + private long system; + // twiddling thumbs + private long idle; + // waiting for I/O to complete + private long iowait; + private long steal; + // virtual processes + private long guest; + private long total; + + // Percentage + private float load_total; + private float load_user; + private float load_system; + private float load_iowait; + private float load_virtual; + + protected CpuStats(){} + protected void update(String[] stats){ + long newUser=0, newNice=0, newSystem=0, newIdle=0, newIowait=0, newIrq=0, newSoftirq=0, newSteal=0, newGuest=0, newGuestNice=0; + if(stats.length >= 1+8){ + newUser = Long.parseLong(stats[1]); + newNice = Long.parseLong(stats[2]); + newSystem = Long.parseLong(stats[3]); + newIdle = Long.parseLong(stats[4]); + newIowait = Long.parseLong(stats[5]); + newIrq = Long.parseLong(stats[6]); + newSoftirq = Long.parseLong(stats[7]); + if(stats.length >= 1+8+3){ + newSteal = Long.parseLong(stats[8]); + newGuest = Long.parseLong(stats[9]); + newGuestNice = Long.parseLong(stats[10]); + } + + // Summarize + newUser = newUser + newNice - newGuest - newGuestNice; + newSystem = newSystem + newIrq + newSoftirq; + newGuest = newGuest + newGuestNice; + + // Calculate the diffs + long userDiff = newUser - user; + long idleDiff = (newIdle + newIowait) - (idle + iowait); + long systemDiff = newSystem - system; + long stealDiff = newSteal - steal; + long virtualDiff = newGuest - guest; + long newTotal = userDiff + systemDiff + idleDiff + stealDiff + virtualDiff; + // Calculate load + load_total = (float)(newTotal-idleDiff)/newTotal; + load_user = (float)userDiff/newTotal; + load_system = (float)systemDiff/newTotal; + load_iowait = (float)(newIowait - iowait)/newTotal; + load_virtual = (float)virtualDiff/newTotal; + + // update old values + user = newUser; + system = newSystem; + idle = newIdle; + iowait = newIowait; + steal = newSteal; + guest = newGuest; + total = newTotal; + } + } + + public float getTotalLoad() { + return load_total; + } + public float getUserLoad() { + return load_user; + } + public float getSystemLoad() { + return load_system; + } + public float getIOWaitLoad() { + return load_iowait; + } + public float getVirtualLoad() { + return load_virtual; + } + + } + +}