View Javadoc

1   package cz.cuni.amis.pogamut.base.utils.logging;
2   
3   import java.util.logging.Level;
4   
5   import javax.management.InstanceAlreadyExistsException;
6   import javax.management.MBeanRegistrationException;
7   import javax.management.MBeanServer;
8   import javax.management.NotCompliantMBeanException;
9   import javax.management.ObjectName;
10  
11  import com.google.inject.Inject;
12  
13  import cz.cuni.amis.pogamut.base.agent.IAgentId;
14  import cz.cuni.amis.pogamut.base.agent.exceptions.CantStartJMXException;
15  import cz.cuni.amis.pogamut.base.agent.exceptions.JMXAlreadyEnabledException;
16  import cz.cuni.amis.pogamut.base.utils.Pogamut;
17  import cz.cuni.amis.pogamut.base.utils.PogamutProperty;
18  import cz.cuni.amis.pogamut.base.utils.guice.AgentScoped;
19  import cz.cuni.amis.pogamut.base.utils.jmx.PogamutJMX;
20  import cz.cuni.amis.pogamut.base.utils.logging.jmx.JMXLogCategories;
21  import cz.cuni.amis.utils.ExceptionToString;
22  
23  /**
24   * All logging apis are fine ... but we don't want to have 
25   * loggers for classes but for instances - therefore we've created
26   * our wrapper allowing you to do two things quickly:
27   * <ol>
28   * <li>log things</li>
29   * <li>create new logger categories</li>
30   * </ol>
31   * 1) that's obvious - it should be easy
32   * <p>
33   * 2) this may prove crucial for your debugging to have own logger
34   * for planner and another for emotions of your agents, etc.
35   * <p><p>
36   * Simply - every Agent instance (starting with the first abstract class
37   * AbstractAgent) has instance of this class (which is java.logging.Logger(s) wrapper).
38   * <p>
39   * Every agent's component has own {@link LogCategory} and you may obtain your own via getCategory() method.
40   * <p><p>
41   * {@link LogCategory} serves as a gateway for your log messages, it contains methods as you
42   * know them from java.logging API (things like fine(), info(), severe(), log(Level, msg), etc.).
43   * <p><p>
44   * Plus it allows you to obtain new {@link LogHandler} instances for that category (if you need to 
45   * publish log messages from that category somewhere else).
46   * <p>
47   * Every {@link LogHandler} serves for filtering messages for one category and publishing them
48   * into one end (console, file, memory, whatever...).
49   * <p><p>
50   * Additionally every {@link LogCategory} has {@link AgentLogger} as its parent.
51   * 
52   * @author Jimmy
53   */
54  @AgentScoped
55  public class AgentLogger extends AbstractAgentLogger {
56  
57      private ILogCategories categories;
58      
59      /**
60       * Name of the logger inside MBean server, initialized when {@link AgentLogger#enableJMX(MBeanServer, ObjectName)} is called.
61       */
62  	private ObjectName objectName;
63  	
64      @Inject
65      public AgentLogger(IAgentId agentId) {
66          super(agentId);
67          this.categories = new LogCategories();
68          String level = Pogamut.getPlatform().getProperty(PogamutProperty.POGAMUT_LOGGER_LEVEL_DEFAULT.getKey());
69          Level logLevel;
70          if (level == null) {
71          	System.err.println("No default level for AgentLogger is specified! Setting WARNING.");
72          	logLevel = Level.WARNING;
73          } else {
74          	try {
75          		logLevel = Level.parse(level);
76          	} catch (Exception e) {
77          		System.err.println("Default AgentLogger level is malformed, could not par log level from: " + level);
78          		System.err.println("Setting log level to WARNING.");
79          		logLevel = Level.WARNING;
80          	}
81          }
82          if (logLevel != null) {
83          	setLevel(logLevel);
84          } else {
85          	setLevel(Level.WARNING);
86          }
87      }
88      
89      public static ObjectName getJMXAgentLoggerName(ObjectName parent) {
90      	return PogamutJMX.getObjectName(parent, PogamutJMX.AGENT_LOGGER_SUBTYPE);
91      }
92  
93      @Override
94      public void enableJMX(MBeanServer mBeanServer, ObjectName parent) throws JMXAlreadyEnabledException, CantStartJMXException {    
95          if (getCategories() instanceof JMXLogCategories) {
96              throw new JMXAlreadyEnabledException("AgentLogger has already JMX turned on.", this);
97          }
98          try {
99          	objectName = ObjectName.getInstance(getJMXAgentLoggerName(parent));
100     		mBeanServer.registerMBean(this, objectName);
101             categories = new JMXLogCategories(getLogCategories(), mBeanServer, parent);
102         } catch (Exception e) {
103             throw new CantStartJMXException(ExceptionToString.process("Can't start JMX for agent logger", e), this);
104         }
105     }
106 
107     @Override
108     protected ILogCategories getLogCategories() {
109         return categories;
110     }
111 
112 }