Source code for /engineering/autohit-2003/src/autohit/common/AutohitBasicLogManager.javaOriginal file AutohitBasicLogManager.java
   1 /**
   2  * AUTOHIT 2003
   3  * Copyright Erich P Gatejen (c) 1989,1997,2003,2004
   4  * 
   5  * This program is free software; you can redistribute it and/or modify 
   6  * it under the terms of the GNU General Public License as published by 
   7  * the Free Software Foundation; either version 2 of the License, or (at
   8  * your option) any later version.
   9  * This program is distributed in the hope that it will be useful, but
  10  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
  11  * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
  12  * more details.
  13  * 
  14  * You should have received a copy of the GNU General Public License along
  15  * with this program; if not, write to the Free Software Foundation, Inc.,
  16  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  17  *
  18  * Additional license information can be found in the documentation.
  19  * @author Erich P Gatejen
  20  */
  21 package autohit.common;
  22 import autohit.common.channels.Atom;
  23 import autohit.common.channels.Controller;
  24 import autohit.common.channels.SimpleChannel;
  25 import autohit.common.AutohitLogDrain;
  26 import autohit.common.channels.Injector;
  27 import autohit.common.channels.SimpleInjector;
  28 import autohit.common.AutohitLogInjectorWrapper;
  29 
  30 import autohit.common.traps.CommonsLoggerTrap;
  31 
  32 import java.util.Hashtable;
  33 import java.util.Enumeration;
  34 
  35 /**
  36  * Basic autohit log manager.  If anyone orders a die or lets an instance
  37  * fall out of scope, it will invalidate all instances (by killing the channel).
  38  * Don't do it.  You should really only have one of these--ever.
  39  * <p>
  40  * This will not create a channel controller!
  41  * @see autohit.common.channels.Controller
  42  * 
  43  * @author Erich P. Gatejen
  44  * @version 1.0
  45  * <i>Version History</i>
  46  * <code>EPG - Rewrite - 23Apr03</code> 
  47  * 
  48  */
  49 public class AutohitBasicLogManager {
  50 
  51 	//private static Controller myLogController;  // we aren't doing this
  52 	private static SimpleChannel controlChannel;
  53 	private static SimpleChannel clientChannel;
  54 	private static AutohitLogDrain controlDrain;
  55 	private static AutohitLogDrain clientDrain;
  56 	private static Injector rootInjector;
  57 	private static AutohitLogInjectorWrapper rootLogger;
  58 	private static Hashtable clientTable;
  59 
  60 	/**
  61 	 * Default constructor.  Creates a generic Drain to System.err.
  62 	 */
  63 	public AutohitBasicLogManager() throws Exception {
  64 		// make sure we only init once.
  65 		if (controlDrain != null)
  66 			return;
  67 
  68 		// Create a generic drain and call the other constructor
  69 		controlDrain = new AutohitLogDrainDefault();
  70 		controlDrain.init(System.err);
  71 		clientDrain =  new AutohitLogDrainDefault();
  72 		clientDrain.init(System.err);
  73 		init(controlDrain, clientDrain);
  74 	}
  75 
  76 	/**
  77 	 * Constructor.  Specifies a specific drain.  You should call this construcot
  78 	 * only once ever during the life of a JVM.
  79 	 * @param control A control drain
  80 	 * @param client A client drain
  81 	 * @throws Exception which is usually a very bad thing.  
  82 	 */
  83 	public AutohitBasicLogManager(AutohitLogDrain control, AutohitLogDrain client) throws Exception {
  84 		if (controlDrain != null)
  85 			throw new Exception("You can only construct with a specific drain once for the life of the JVM.");
  86 		controlDrain = control;
  87 		clientDrain =  client;
  88 		init(control, client);
  89 	}
  90 
  91 	/**
  92 	 * Constructor.  Specifies a specific drain.
  93 	 * @param control A control drain
  94 	 * @param client A client drain
  95 	 * @see autohit.common.AutohitLogDrain
  96 	 * @throws Exception Which usually means something very bad happened.
  97 	 */
  98 	private void init(AutohitLogDrain control, AutohitLogDrain client) throws Exception {
  99 
 100 		// Create the channels
 101 		controlChannel = new SimpleChannel();
 102 		clientChannel = new SimpleChannel();
 103 		
 104 		// Register Drains
 105 		controlChannel.register(AutohitProperties.LOGS_CONTROL_DRAIN, control);
 106 		clientChannel.register(AutohitProperties.LOGS_CLIENT_DRAIN, client);
 107 
 108 		// Register the root Injector
 109 		rootInjector = new SimpleInjector();
 110 		rootLogger = new AutohitLogInjectorWrapper();
 111 		rootLogger.init(AutohitProperties.LOGS_ROOT_ID, rootInjector);
 112 		controlChannel.register(AutohitProperties.LOGS_CONTROL_INJECTOR, rootInjector);
 113 
 114 		// Set routing
 115 		controlChannel.requestLevel(AutohitProperties.LOGS_CONTROL_DRAIN, Atom.P_TOP);
 116 		controlChannel.requestType(AutohitProperties.LOGS_CONTROL_DRAIN, Atom.TYPE_LOG);
 117 		clientChannel.requestLevel(AutohitProperties.LOGS_CLIENT_DRAIN, Atom.P_TOP);
 118 		clientChannel.requestType(AutohitProperties.LOGS_CLIENT_DRAIN, Atom.TYPE_LOG);
 119 		// for future compatibility
 120 
 121 		// Register the channels
 122 		Controller.register(AutohitProperties.LOGS_CONTROL_STATION, controlChannel);
 123 		Controller.register(AutohitProperties.LOGS_CLIENT_STATION, clientChannel);
 124 
 125 		// Trap any commons loggers
 126 		// TODO move this to some other channel
 127 		CommonsLoggerTrap.setTrap(rootLogger);
 128 
 129 		// Make Logger cache
 130 		clientTable = new Hashtable();
 131 	}
 132 
 133 	/**
 134 	 * Get the root logger.
 135 	 * @return a reference to the root AutohitLogInjectorWrapper, which wraps the root injector
 136 	 * @see autohit.common.AutohitLogInjectorWrapper
 137 	 */
 138 	public AutohitLogInjectorWrapper getRootLogger() {
 139 		return rootLogger;
 140 	}
 141 
 142 	/**
 143 	 * Get the root injector.
 144 	 * @return a reference to the root Injector
 145 	 * @see autohit.common.AutohitLogInjectorWrapper
 146 	 */
 147 	public Injector getRootInjector() {
 148 		return rootInjector;
 149 	}
 150 
 151 	/**
 152 	 * Add an injector to the client channel. It is a very good idea to 
 153 	 * discard the logger when you are done.
 154 	 * @param il An injector
 155 	 * @param id A string id for the sender.  Technically, it doesn't have to be unique.
 156 	 * @see autohit.common.channels.Injector
 157 	 */
 158 	public void addClient(Injector il, String id) throws Exception {
 159 
 160 			String registerID = AutohitProperties.LOGS_CLIENT_INJECTOR + id;
 161 				
 162 			// Register it
 163 			clientChannel.register(registerID, il);
 164 			clientTable.put(registerID, il);
 165 	}
 166 
 167 	/**
 168 	 * It will discard a client injector
 169 	 * @param id A string id for the sender.  Needs to be the same as the one use to register it.
 170 	 */
 171 	public void discardClient(String id) {
 172 
 173 		try {
 174 
 175 			// if it is in the cache, use it
 176 			if (clientTable.containsKey(id)) {
 177 				clientTable.remove(id);
 178 				clientChannel.removeInjector(id);
 179 			}
 180 
 181 		} catch (Exception e) { // don't care.  null should return
 182 		}
 183 	}
 184 
 185 	/**
 186 	 * Set pretty formatting on output
 187 	 * @param p Set TRUE for on.
 188 	 */
 189 	public void pretty(boolean p) {
 190 		controlDrain.setPrettyFlag(p);
 191 		clientDrain.setPrettyFlag(p);
 192 	}
 193 
 194 	/**
 195 	 * Set timestamp formatting on output
 196 	 * @param p Set TRUE for on.
 197 	 */
 198 	public void stampit(boolean p) {
 199 		controlDrain.setTimestampFlag(p);
 200 		clientDrain.setTimestampFlag(p);
 201 	}
 202 
 203 	/**
 204 	 * Get primary drain
 205 	 * @return the primary log drain
 206 	 */
 207 	public AutohitLogDrain getDrain() {
 208 		return controlDrain;
 209 	}
 210 
 211 	/**
 212 	 * Get client drain
 213 	 * @return the client log drain
 214 	 */
 215 	public AutohitLogDrain getClientDrain() {
 216 		return clientDrain;
 217 	}
 218 
 219 	/**
 220 	 * Discard client drain writer.  This is a terrible hack.
 221 	 * @param id the id of the drain writer to discard
 222 	 */
 223 	public void discardDrainWriter(String id) {
 224 		try {
 225 			clientDrain.discardWriter(id);
 226 		} catch (Exception e) {
 227 			// do nothing
 228 		}
 229 	}
 230 
 231 	/**
 232 	 * Turn debug logging on.  It will turn debugging on for the root logger, but 
 233 	 * not any clients!  you have to do that yourself.
 234 	 */
 235 	public void debugOn() {
 236 		try {
 237 			rootLogger.debugFlag(true);
 238 			clientChannel.requestLevel(
 239 				AutohitProperties.LOGS_CLIENT_DRAIN,
 240 				Atom.P_TOP);
 241 			controlChannel.requestLevel(
 242 				AutohitProperties.LOGS_CONTROL_DRAIN,
 243 				Atom.P_TOP);				
 244 		} catch (Exception e) {
 245 			System.out.println(
 246 				"!! LOGGING system failure.  Cannot debugOn() for autohit.*.drain."
 247 					+ e.getMessage());
 248 		}
 249 	}
 250 
 251 	/**
 252 	 * Turn debug logging off
 253 	 */
 254 	public void debugOff() {
 255 		try {
 256 			rootLogger.debugFlag(false);
 257 			clientChannel.requestLevel(
 258 				AutohitProperties.LOGS_CLIENT_DRAIN ,
 259 				Atom.ROUTINE);
 260 			controlChannel.requestLevel(
 261 				AutohitProperties.LOGS_CONTROL_DRAIN ,
 262 				Atom.ROUTINE);			
 263 		} catch (Exception e) {
 264 			System.out.println(
 265 				"!! LOGGING system failure.  Cannot debugOff() for autohit.*.drain."
 266 					+ e.getMessage());
 267 		}
 268 	}
 269 
 270 	/**
 271 	 * Die
 272 	 */
 273 	public void die() {
 274 		try {
 275 
 276 			// Pull drain and all injectors
 277 			controlChannel.removeDrain(AutohitProperties.LOGS_CONTROL_DRAIN );
 278 			controlChannel.removeInjector(AutohitProperties.LOGS_CONTROL_INJECTOR);
 279 			clientChannel.removeDrain(AutohitProperties.LOGS_CLIENT_DRAIN);
 280 			try {
 281 				Object thingthang;
 282 				for (Enumeration e = clientTable.keys(); e.hasMoreElements();) {
 283 					thingthang = e.nextElement();
 284 					clientTable.remove(e);
 285 					clientChannel.removeInjector((String) thingthang);
 286 				}
 287 			} catch (Exception efc) { //dont care
 288 			}
 289 
 290 			// Unregister channel
 291 			Controller.remove(AutohitProperties.LOGS_CONTROL_STATION);
 292 			Controller.remove(AutohitProperties.LOGS_CLIENT_STATION);
 293 
 294 		} catch (Exception e) { // don't really care - FUBAR
 295 		}
 296 		clientChannel = null;
 297 		controlChannel = null;
 298 	}
 299 
 300 	/*
 301 	 * finalizer
 302 	 * Make sure the log handler is unhooked
 303 	 */
 304 	protected void finalize() throws Throwable {
 305 		super.finalize();
 306 		this.die();
 307 	}
 308 
 309 }