/* * ALMA - Atacama Large Millimiter Array (c) European Southern Observatory, 2010 * * This library is free software; you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License as published by the Free * Software Foundation; either version 2.1 of the License, or (at your option) * any later version. * * This library 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 Lesser General Public License for more * details. * * You should have received a copy of the GNU Lesser General Public License * along with this library; if not, write to the Free Software Foundation, Inc., * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * */ package alma.acs.logtools.monitor.file; import com.cosylab.logging.engine.log.LogTypeHelper; import alma.acs.logtools.monitor.LogDetailsDispatcher; import alma.acs.logtools.monitor.LogNumbersListener; import alma.acs.logtools.monitor.TotalStatsData; import alma.acs.util.IsoDateFormat; /** * Write the statistics on a set of files. * <P> * The number of logs per interval are immediately written on file. * The total numbers instead are written by the thread. * * @author acaproni * @since ACS 8.1.0 */ public class FileStatistics extends Thread implements LogNumbersListener { /** * A class to ensure mutual exclusion while updating/reading values * @author acaproni * */ private class StatsData extends TotalStatsData { /** * Format the string of values to write on file * * @return the string of values to write on file */ public synchronized String formatString() { // Build the string to write on file StringBuilder str = new StringBuilder(IsoDateFormat.formatCurrentDate()); for (int t=0; t<totalLogs.length; t++) { str.append(String.format(" %d %.2f",totalLogs[t],logsTypeDistribution[t])); } str.append(String.format(" %d %d %d %d\n", numOfLogs, shortestLogSize, longestLogSize, errors)); return str.toString(); } } /** * The interval of time (sec) between writing of total numbers */ private final int WRITE_TOT_INTERVAL=10; /** * signal the thread to terminate */ private boolean terminateThread=false; /** * The file to write the logs receives for each time interval */ private final FileHelper recvLogsFile; /** * The file to write the statistics about the logs received since * the application started. */ private final FileHelper totLogsStatsFile; /** * The values of the totals numbers */ private final StatsData totData = new StatsData(); /** * constructor * * @param folder The folder to write files into */ public FileStatistics(String folder) { super(FileStatistics.class.getName()); if (folder==null || folder.isEmpty()) { throw new IllegalArgumentException("Invalid folder"); } recvLogsFile= new FileHelper(folder, "logsFlow",generateRecvLogsHdr()); totLogsStatsFile= new FileHelper(folder, "logsStats",generateTotLogsHdr()); // start the thread setDaemon(true); start(); } /** * Notified every time interval about the number of * logs of each type received during the interval. * <P> * The numbers are immediately written on file. * * @see alma.acs.logtools.monitor.LogNumbersListener#recvLogs(int[], int) */ @Override public synchronized void recvLogs(int[] nums, int secs) { StringBuilder str = new StringBuilder(IsoDateFormat.formatCurrentDate()); for (int n: nums) { float f=(float)n/(float)LogDetailsDispatcher.NUMBER_LISTENERS_INTERVAL; str.append(String.format(" %5d %.3f",n,f)); } str.append('\n'); recvLogsFile.put(str.toString()); } /** * Close the computation and frees the resources */ public void close() { terminateThread=true; interrupt(); recvLogsFile.close(); totLogsStatsFile.close(); } /** * Generate the header string for the received logs * * @return */ private String generateRecvLogsHdr() { StringBuilder ret = new StringBuilder("# timestamp"); for (LogTypeHelper type: LogTypeHelper.values()) { ret.append(' '); ret.append(type.toString()); ret.append(' '); ret.append(type.toString()); ret.append("/sec"); } ret.append('\n'); return ret.toString(); } /** * Generate the header string for the received logs * * @return */ private String generateTotLogsHdr() { StringBuilder ret = new StringBuilder("# timestamp"); for (LogTypeHelper type: LogTypeHelper.values()) { ret.append(' '); ret.append(type.toString()); ret.append(" %"); ret.append(type.toString()); } ret.append(" totalLogs shortestSize longestSize errors"); ret.append('\n'); return ret.toString(); } /** * Notify the listener about the total number of logs * read since the application started. * * @param d The total number of logs read since the application started * @see LogNumbersListener */ @Override public void totalData(TotalStatsData d) { totData.updateAll(d); } /** * The thread to write total values on file */ @Override public void run() { while (!terminateThread) { try { Thread.sleep(WRITE_TOT_INTERVAL*1000); } catch (InterruptedException ie) { continue; } String str=totData.formatString(); totLogsStatsFile.put(str); } } }