📄 jrobinlogger.java
字号:
package net.sf.dz.daemon.logger;import java.awt.Color;import java.io.BufferedReader;import java.io.File;import java.io.FileReader;import java.io.IOException;import java.util.Date;import java.util.Iterator;import java.util.LinkedList;import java.util.List;import java.util.StringTokenizer;import org.jrobin.core.Sample;import org.jrobin.core.RrdDb;import org.jrobin.core.RrdDef;import org.jrobin.core.RrdException;import org.jrobin.graph.RrdGraph;import org.jrobin.graph.RrdGraphDef;import org.freehold.jukebox.conf.Configuration;import org.freehold.jukebox.logger.LogChannel;import net.sf.dz.util.Round;/** * The RRD logger. * * Listens to the notifications and writes them into the trace file and RRD * database. * * <p> * * This class, as opposed to {@link RRDLogger RRDLogger}, uses native <a * href="http://jrobin.sourceforge.net/" target="_top">JRobin</a> library to * manipulate the RRD database. * * @author Copyright © <a href="mailto:vt@freehold.crocodile.org">Vadim Tkachenko</a> 2004 * @version $Id: JRobinLogger.java,v 1.4 2004/07/02 07:34:18 vtt Exp $ */public class JRobinLogger extends AbstractLogger { public static final LogChannel CH_LOGGER = new LogChannel("Logger/JRobin"); private RrdDb rrd = null; private List intervalDefs = new LinkedList(); private File imageDir; private Color graphColors[] = { Color.RED, Color.GREEN, Color.BLUE, Color.YELLOW, Color.CYAN, Color.MAGENTA, Color.ORANGE, Color.PINK, Color.GRAY }; protected void configure() throws Throwable { super.configure(); Configuration cf = getConfiguration(); String cfroot = getConfigurationRoot(); imageDir = new File(cf.getString(cfroot + ".rrd_logger.imagedir", "/tmp")); if ( !imageDir.exists() || !imageDir.isDirectory() || !imageDir.canWrite() ) { throw new IllegalArgumentException(imageDir.toString() + ": bad configuration value: doesn't exist, not a directory or not writable"); } complain(LOG_INFO, CH_LOGGER, "Image directory: " + imageDir); } protected void startup() throws Throwable { super.startup(); generateIntervalDefinitions(); open(); } protected void rrdupdate(String entry) throws IOException, RrdException { if ( !open() ) { // They've already complained return; } long start = System.currentTimeMillis(); try { Sample sample = rrd.createSample(); StringTokenizer st = new StringTokenizer(entry, ":"); sample.setTime(Long.parseLong(st.nextToken())); for ( int offset = 0; st.hasMoreTokens(); offset++ ) { String stringValue = st.nextToken(); double doubleValue = 0; if ( "U".equals(stringValue) ) { doubleValue = Double.NaN; } else { doubleValue = Double.parseDouble(stringValue); } try { sample.setValue(offset, doubleValue); } catch ( Throwable t ) { // This is most likely not a fatal error, but something like // "out of index" which may happen if there's a // mis-synchronization between the trace file and the actual // RRD database. complain(LOG_WARNING, CH_LOGGER, "sample.setValue(" + offset + ", " + doubleValue + ") failed: " + t.getMessage()); } } // Since we're not dealing with the command line, (I hope) there's // no need to pad the sample try { sample.update(); } catch ( RrdException ex ) { if ( ex.getMessage() != null ) { if ( ex.getMessage().startsWith("Bad sample timestamp") ) { // No big deal complain(LOG_WARNING, CH_LOGGER, "rrdupdate(): " + ex.getMessage()); } else { // I don't know what it is throw ex; } } } } finally { complain(LOG_DEBUG, CH_LOGGER, "rrdupdate(): " + (System.currentTimeMillis() - start) + "ms"); } } private synchronized boolean open() { if ( rrd != null ) { return true; } File rrdFile = new File(getRrdLocation()); if ( !rrdFile.exists() ) { complain(LOG_WARNING, CH_LOGGER, "RRD doesn't (yet?) exist: " + getRrdLocation()); File traceFile = new File(getTraceLocation()); if ( !traceFile.exists() ) { complain(LOG_WARNING, CH_LOGGER, "No trace file either?: " + getTraceLocation()); return false; } else { try { regenerateRRD(); } catch ( Throwable t ) { complain(LOG_ERR, CH_LOGGER, "Failed to regenerate RRD:", t); return false; } return open(); } } long start = System.currentTimeMillis(); try { rrd = new RrdDb(getRrdLocation()); generateIntervalDefinitions(); return true; } catch ( Throwable t ) { complain(LOG_WARNING, CH_LOGGER, "Can't open " + getRrdLocation() + ":", t); return false; } finally { complain(LOG_DEBUG, CH_LOGGER, "open() took " + (System.currentTimeMillis() - start) + "ms"); } } private synchronized void close() throws IOException { if ( rrd != null ) { rrd.close(); } resetIntervalDefinitions(); rrd = null; } protected synchronized void regenerateRRD() throws Throwable { complain(LOG_NOTICE, CH_LOGGER, "Regenerating RRD..."); rotateRRD(0); createRRD(); refillRRD(); complain(LOG_NOTICE, CH_LOGGER, "Done regenerating RRD."); } protected void rotateRRD(int offset) throws IOException { close(); String suffix = (offset == 0) ? "" : ("." + offset); String nextSuffix = "." + (offset + 1); File currentFile = new File(getRrdLocation() + suffix); if ( !currentFile.exists() ) { return; } final int maxCopies = 20; File nextFile = new File(getRrdLocation() + nextSuffix); if ( nextFile.exists() && (offset < maxCopies - 1) ) { // Next one exists, and it's number is less then maximum allowed rotateRRD(offset + 1); } // Now that the next copy is out of the way, let's rename the // current one if ( !currentFile.renameTo(nextFile) ) { throw new IOException("Couldn't rename " + currentFile + " to " + nextFile); } } protected void createRRD() throws IOException, RrdException { close(); complain(LOG_NOTICE, CH_LOGGER, "Creating RRD"); long start = System.currentTimeMillis(); RrdDef def = new RrdDef(getRrdLocation()); // Let it be Jan 01 2000 def.setStartTime(946710000L); def.setStep(30); for ( Iterator i = iterator(); i.hasNext(); ) { String device = i.next().toString(); def.addDatasource(device, "GAUGE", 90, -60, 85); } def.addArchive("LAST", 0.5, 1, 5760); def.addArchive("MIN", 0.5, 1, 5760);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -