]> git.argeo.org Git - lgpl/argeo-commons.git/blob - KernelThread.java
5ebf4055fb2dce6e6d66e0392b8ef223d519be4c
[lgpl/argeo-commons.git] / KernelThread.java
1 package org.argeo.cms.internal.kernel;
2
3 import java.io.File;
4 import java.lang.management.ManagementFactory;
5
6 import org.apache.commons.logging.Log;
7 import org.apache.commons.logging.LogFactory;
8 import org.apache.jackrabbit.api.stats.RepositoryStatistics;
9 import org.apache.jackrabbit.stats.RepositoryStatisticsImpl;
10 import org.argeo.cms.CmsException;
11 import org.argeo.cms.internal.auth.CmsSessionImpl;
12
13 /**
14 * Background thread started by the {@link Kernel}, which gather statistics and
15 * monitor/control other processes.
16 */
17 class KernelThread extends Thread {
18 private RepositoryStatisticsImpl repoStats;
19
20 /** The smallest period of operation, in ms */
21 private final long PERIOD = 60 * 1000l;
22 /** One ms in ns */
23 private final static long m = 1000l * 1000l;
24 private final static long M = 1024l * 1024l;
25
26 private boolean running = true;
27
28 private Log kernelStatsLog = LogFactory.getLog("argeo.stats.kernel");
29 private Log nodeStatsLog = LogFactory.getLog("argeo.stats.node");
30
31 @SuppressWarnings("unused")
32 private long cycle = 0l;
33
34 public KernelThread(ThreadGroup threadGroup, String name) {
35 super(threadGroup, name);
36 }
37
38 private void doSmallestPeriod() {
39 // Clean expired sessions
40 CmsSessionImpl.closeInvalidSessions();
41
42 if (kernelStatsLog.isDebugEnabled()) {
43 StringBuilder line = new StringBuilder(64);
44 line.append(\t");
45 long freeMem = Runtime.getRuntime().freeMemory() / M;
46 long totalMem = Runtime.getRuntime().totalMemory() / M;
47 long maxMem = Runtime.getRuntime().maxMemory() / M;
48 double loadAvg = ManagementFactory.getOperatingSystemMXBean().getSystemLoadAverage();
49 // in min
50 boolean min = true;
51 long uptime = ManagementFactory.getRuntimeMXBean().getUptime() / (1000 * 60);
52 if (uptime > 24 * 60) {
53 min = false;
54 uptime = uptime / 60;
55 }
56 line.append(uptime).append(min ? " min" : " h").append('\t');
57 line.append(loadAvg).append('\t').append(maxMem).append('\t').append(totalMem).append('\t').append(freeMem)
58 .append('\t');
59 kernelStatsLog.debug(line);
60 }
61
62 if (nodeStatsLog.isDebugEnabled()) {
63 File dataDir = KernelUtils.getOsgiInstanceDir();
64 long freeSpace = dataDir.getUsableSpace() / M;
65 // File currentRoot = null;
66 // for (File root : File.listRoots()) {
67 // String rootPath = root.getAbsolutePath();
68 // if (dataDir.getAbsolutePath().startsWith(rootPath)) {
69 // if (currentRoot == null
70 // || (rootPath.length() > currentRoot.getPath()
71 // .length())) {
72 // currentRoot = root;
73 // }
74 // }
75 // }
76 // long totalSpace = currentRoot.getTotalSpace();
77 StringBuilder line = new StringBuilder(128);
78 line.append(\t").append(freeSpace).append(" MB left in " + dataDir);
79 line.append('\n');
80 if (repoStats != null)
81 for (RepositoryStatistics.Type type : RepositoryStatistics.Type.values()) {
82 long[] vals = repoStats.getTimeSeries(type).getValuePerMinute();
83 long val = vals[vals.length - 1];
84 line.append(type.name()).append('\t').append(val).append('\n');
85 }
86 nodeStatsLog.debug(line);
87 }
88 }
89
90 @Override
91 public void run() {
92 final long periodNs = PERIOD * m;
93 while (running) {
94 long beginNs = System.nanoTime();
95 doSmallestPeriod();
96
97 long waitNs = periodNs - (System.nanoTime() - beginNs);
98 if (waitNs < 0)
99 continue;
100 // wait
101 try {
102 sleep(waitNs / m, (int) (waitNs % m));
103 } catch (InterruptedException e) {
104 // silent
105 }
106 cycle++;
107 }
108 }
109
110 synchronized void destroyAndJoin() {
111 running = false;
112 notifyAll();
113 interrupt();
114 try {
115 join(PERIOD * 2);
116 } catch (InterruptedException e) {
117 throw new CmsException("Kernel thread destruction was interrupted");
118 }
119 }
120 }