001/* 002 * jPOS Project [http://jpos.org] 003 * Copyright (C) 2000-2026 jPOS Software SRL 004 * 005 * This program is free software: you can redistribute it and/or modify 006 * it under the terms of the GNU Affero General Public License as 007 * published by the Free Software Foundation, either version 3 of the 008 * License, or (at your option) any later version. 009 * 010 * This program is distributed in the hope that it will be useful, 011 * but WITHOUT ANY WARRANTY; without even the implied warranty of 012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 013 * GNU Affero General Public License for more details. 014 * 015 * You should have received a copy of the GNU Affero General Public License 016 * along with this program. If not, see <http://www.gnu.org/licenses/>. 017 */ 018 019package org.jpos.util; 020 021import org.jpos.core.Configurable; 022import org.jpos.core.Configuration; 023import org.jpos.core.ConfigurationException; 024import org.jpos.q2.Q2; 025 026import java.util.ArrayList; 027import java.util.Collections; 028import java.util.ConcurrentModificationException; 029import java.util.Iterator; 030import java.util.List; 031 032/** 033 * Peer class Logger forwards LogEvents generated by LogSources 034 * to LogListeners. 035 * <br> 036 * This little <a href="/doc/LoggerGuide.html">tutorial</a> 037 * give you additional information on how to extend the jPOS's 038 * Logger subsystem. 039 * 040 * @author apr@cs.com.uy 041 * @version $Id$ 042 * @see LogEvent 043 * @see LogSource 044 * @see LogListener 045 * @see Loggeable 046 * @see SimpleLogListener 047 * @see RotateLogListener 048 */ 049@SuppressWarnings("unchecked") 050public class Logger implements LogProducer,Configurable 051{ 052 Configuration cfg; 053 String name; 054 List<LogListener> listeners; 055 /** Prefix used to register loggers in {@code NameRegistrar}. */ 056 public static final String NRPREFIX = "logger."; 057 058 /** Default constructor. */ 059 public Logger () { 060 super(); 061 listeners = Collections.synchronizedList(new ArrayList<>()); 062 name = ""; 063 } 064 065 /** Returns the current configuration. 066 * @return configuration object 067 */ 068 public Configuration getConfiguration() 069 { 070 return cfg; 071 } 072 073 @Override 074 /** Configures this Logger instance. 075 * @param cfg the new configuration 076 * @throws ConfigurationException on configuration error 077 */ 078 public void setConfiguration(Configuration cfg) throws ConfigurationException 079 { 080 this.cfg = cfg; 081 } 082 083 /** Adds a log listener to this logger. 084 * @param l the listener to add 085 */ 086 public void addListener (LogListener l) { 087 listeners.add(l); 088 } 089 public void removeListener (LogListener l) { 090 listeners.remove(l); 091 } 092 public void removeAllListeners () { 093 for (Object l : listeners) { 094 if (l instanceof Destroyable) { 095 ((Destroyable) l).destroy(); 096 } 097 } 098 listeners.clear (); 099 } 100 /** Dispatches a log event to the appropriate logger and its listeners. 101 * @param evt the log event to dispatch 102 */ 103 public static void log (LogEvent evt) { 104 Logger l = null; 105 LogSource source = evt.getSource(); 106 if (source != null) 107 l = source.getLogger(); 108 if (l == null && !evt.isHonorSourceLogger()) { 109 l = getLogger(Q2.LOGGER_NAME); 110 } 111 if (l != null && l.hasListeners ()) { 112 Iterator<LogListener> i = l.listeners.iterator(); 113 while (i.hasNext() && evt != null) { 114 try { 115 evt = i.next().log(evt); 116 } catch (ConcurrentModificationException e) { 117 break; 118 } catch (Throwable t) { 119 evt.addMessage (t); 120 } 121 } 122 } 123 } 124 /** 125 * associates this Logger with a name using NameRegistrar 126 * @param name name to register 127 * @see NameRegistrar 128 */ 129 public void setName (String name) { 130 this.name = name; 131 NameRegistrar.register (NRPREFIX+name, this); 132 } 133 /** 134 * destroy logger 135 */ 136 public void destroy () { 137 NameRegistrar.unregister (NRPREFIX+name); 138 removeAllListeners (); 139 } 140 /** 141 * Returns the logger instance registered under the given name, creating one if necessary. 142 * @param name the logger name 143 * @return logger instance with given name. Creates one if necessary 144 * @see NameRegistrar 145 */ 146 public synchronized static Logger getLogger (String name) { 147 Logger l; 148 try { 149 l = NameRegistrar.get (NRPREFIX+name); 150 } catch (NameRegistrar.NotFoundException e) { 151 l = new Logger(); 152 l.setName (name); 153 } 154 return l; 155 } 156 /** 157 * Returns this logger's registered name. 158 * @return this logger's name ("" if no name was set) 159 */ 160 public String getName() { 161 return this.name; 162 } 163 /** 164 * Used by heavy used methods to avoid LogEvent creation 165 * @return true if Logger has associated LogListsners 166 */ 167 public boolean hasListeners() { 168 return !listeners.isEmpty(); 169 } 170}