View Javadoc

1   package cz.cuni.amis.pogamut.base.utils.logging;
2   
3   import java.util.logging.Level;
4   import java.util.logging.Logger;
5   
6   import cz.cuni.amis.pogamut.base.agent.impl.AgentId;
7   import cz.cuni.amis.pogamut.base.utils.logging.marks.LogEventMark;
8   import cz.cuni.amis.pogamut.base.utils.logging.marks.LogMapMark;
9   import cz.cuni.amis.pogamut.base3d.worldview.object.Location;
10  
11  /**
12   * Instance that serves as a gateway for your log messages.
13   * <p><p>
14   * The trick with categories is that every log record may contain
15   * object parameters. So we're appending instance of this class as
16   * a very first parameter to the log record and filter those messages
17   * according to them.
18   * 
19   * @author Jimmy
20   */
21  public class LogCategory extends Logger implements Comparable<LogCategory> {
22  	
23  	private String categoryName;
24  	
25  	private Object mutex = new Object();
26  
27  	private Logger parent;
28  	
29  	public LogCategory(String categoryName) {
30  		this(categoryName, null);
31  	}
32  	
33  	public LogCategory(String categoryName, Logger parent) {
34  		super(categoryName, null);
35  		this.parent = parent;
36  		this.categoryName = categoryName;
37  	}
38  	
39  	public String getCategoryName() {
40  		return categoryName;
41  	}
42  	
43  	@Override
44  	public void setLevel(Level logLevel) throws SecurityException {
45  		if (logLevel == null) return;
46  		if (getLevel() == logLevel) return;
47  		if (getLevel() != null) { 
48  			log(getLevel(), "Log level set to " + logLevel + ".");
49  		} else {
50  			log(Level.WARNING, "Log level set to " + logLevel + ".");
51  		}
52  		super.setLevel(logLevel);
53  	}
54  	
55  	/**
56  	 * Adds default console handler with 'Platform' (== platform logging) agent id.
57  	 * <p><p>
58  	 * Use only when using {@link LogCategory} separately, i.e., outside {@link IAgentLogger}.
59  	 * 
60  	 * @return this instance
61  	 */
62  	public LogCategory addConsoleHandler() {
63  		addHandler(new LogPublisher.ConsolePublisher(new AgentId("Platform")));
64  		return this;
65  	}
66  	
67  	/**
68  	 * Returns new LogHandler with null ILogPublisher that is appended
69  	 * to the logger and filters log messages for this category.
70  	 * <p><p>
71  	 * The handler will use LogPublisher.ConsolePublisher as default.
72  	 * <p><p>
73  	 * This is the quickest way to obtain new output from the log. 
74  	 * 
75  	 * @return
76  	 */
77  	public LogHandler addHandler() {
78  		return addHandler((ILogPublisher)null);
79  	}
80  	
81  	/**
82  	 * Returns new LogHandler with specified ILogPublisher that is appended
83  	 * to the logger and filters log messages for this category.
84  	 * <p><p>
85  	 * The handler will use LogPublisher.ConsolePublisher as default.
86  	 * <p><p>
87  	 * This is the quickest way to obtain new output from the log. 
88  	 * 
89  	 * @return
90  	 */
91  	public LogHandler addHandler(ILogPublisher publisher) {
92  		LogHandler handler = new LogHandler();
93  		handler.setFilter(new LogCategoryFilter(this));
94  		handler.setPublisher(publisher);
95  		this.addHandler(handler);
96  		return handler;
97  	}
98  		
99  	/**
100 	 * All other logging methods is calling this one. Synchronized!
101 	 */
102 	@Override
103 	public void log(Level level, String msg, Object[] params) {
104 		synchronized(mutex) {
105 			if (params.length == 0) {
106 				super.log(level, msg, this.getCategoryName());
107 				if (parent != null) parent.log(level, msg, this.getCategoryName());
108 			} else {
109 				Object[] finalParams = new Object[params.length+1];
110 				finalParams[0] = this.getCategoryName();
111 				System.arraycopy(params, 0, finalParams, 1, params.length);
112 				super.log(level, msg, finalParams);
113 				if (parent != null) parent.log(level, msg, this.getCategoryName());
114 			}
115 		}
116 	}
117 	
118 	@Override
119 	public void log(Level level, String msg) {
120 		log(level, msg, new Object[0]);
121 	}
122 	
123 	@Override
124 	public void log(Level level, String msg, Object param) {
125 		log(level, msg, new Object[]{param});
126 	}
127 	
128 	@Override
129 	public void finest(String msg) {
130 		log(Level.FINEST, msg);
131 	}
132 	
133 	public void finest(String msg, Object param) {
134 		log(Level.FINEST, msg, param);
135 	}
136 	
137 	public void finest(String msg, Object[] params) {
138 		log(Level.FINEST, msg, params);
139 	}
140 	
141 	@Override
142 	public void finer(String msg) {
143 		log(Level.FINER, msg);
144 	}
145 	
146 	public void finer(String msg, Object param) {
147 		log(Level.FINER, msg, param);
148 	}
149 	
150 	public void finer(String msg, Object[] params) {
151 		log(Level.FINER, msg, params);
152 	}
153 	
154 	@Override
155 	public void fine(String msg) {
156 		log(Level.FINE, msg);
157 	}
158 	
159 	public void fine(String msg, Object param) {
160 		log(Level.FINE, msg, param);
161 	}
162 	
163 	public void fine(String msg, Object[] params) {
164 		log(Level.FINE, msg, params);
165 	}
166 	
167 	@Override
168 	public void info(String msg) {
169 		log(Level.INFO, msg);
170 	}
171 	
172 	public void info(String msg, Object param) {
173 		log(Level.INFO, msg, param);
174 	}
175 	
176 	public void info(String msg, Object[] params) {
177 		log(Level.INFO, msg, params);
178 	}
179 	
180 	@Override
181 	public void warning(String msg) {
182 		log(Level.WARNING, msg);
183 	}
184 	
185 	public void warning(String msg, Object param) {
186 		log(Level.WARNING, msg, param);
187 	}
188 	
189 	public void warning(String msg, Object[] params) {
190 		log(Level.WARNING, msg, params);
191 	}
192 	
193 	@Override
194 	public void severe(String msg) {
195 		log(Level.SEVERE, msg);
196 	}
197 	
198 	public void severe(String msg, Object param) {
199 		log(Level.SEVERE, msg, param);
200 	}
201 	
202 	public void severe(String msg, Object[] params) {
203 		log(Level.SEVERE, msg, params);
204 	}
205 
206 	@Override
207 	public String toString() {
208 		return "LogCategory("+getName()+")";
209 	}
210 
211 	@Override
212 	public int compareTo(LogCategory o) {
213 		if (o.categoryName == null) {
214 			if (categoryName == null) return 0;
215 			return -1;
216 		} else
217 		if (categoryName == null) {
218 			return 1;
219 		}
220 		return o.categoryName.compareTo(categoryName);
221 	}
222 
223 
224     /**
225      * Add mark to the map for specified time and add notice to the logs.
226      * @param level What level is this mark? If too low, it can be filtered out.
227      * @param msg What text should be shown on the map at the specified place.
228      * @param location Location, where should be mark placed. If null, mark will follow the agent.
229      * @param duration How long should be mark shown? In ms.
230      */
231     public void addMapMark(Level level, String msg, Location location, long duration) {
232         String text4log = "[Map mark](" + duration + "ms) " + msg;
233         LogMapMark mark = LogMapMark.createFixedLengthEvent(level, msg, location, duration);
234 
235         log(level, text4log, mark);
236     }
237 
238     /**
239      * Add mark to the map. If you want to remove the mark, use {@link LogCategory#removeMapMark(java.lang.Object) }
240      *
241      * @param level What level is this mark? If too low, it can be filtered out.
242      * @param msg What text should be shown on the map at the specified place.
243      * @param location Location, where should be mark placed. If null, mark will follow the agent.
244      * @return object that can be later used in {@link LogCategory#removeMapMark(java.lang.Object) } in order to remove the mark from the map.
245      */
246     public LogMapMark addMapMark(Level level, String msg, Location location) {
247         LogMapMark mark = LogMapMark.createVariableLengthEvent(level, msg, location);
248         String text4log = "[Map mark](START:" + mark.getId() + ") " + msg;
249 
250         log(level, text4log, mark);
251 
252         return mark;
253     }
254 
255     /**
256      * Remove mark from the map. Mark should be previosly inserted using {@link LogCategory#addMapMark(java.util.logging.Level, java.lang.String, cz.cuni.amis.pogamut.base3d.worldview.object.Location) }
257      * @param mark object that was returned by {@link LogCategory#addMapMark(java.util.logging.Level, java.lang.String, cz.cuni.amis.pogamut.base3d.worldview.object.Location) }
258      *             during addition of mark to the map.
259      */
260     public void removeMapMark(LogMapMark mark) {
261         assert mark!= null;
262 
263         String text4log = "[Map mark](END:" + mark.getId() + ") " + mark.getMessage();
264 
265         log(mark.getLevel(), text4log, mark.getEndMark());
266     }
267 
268     /**
269      * Add log message to the log. Log message is log event with zero duration.
270      * @param text text of log message.
271      */
272     public void addLogMessage(Level level, String text) {
273         LogEventMark mark = LogEventMark.createSingleLengthEvent(level, text);
274         String text4log = "[Log event](message) " + text;
275 
276         log(level, text4log, mark);
277     }
278 
279     /**
280      * Add new log event to the log, the event starts now.
281      * @param level level of event. 
282      * @param text text of event
283      * @param duration how long should event last?
284      */
285     public void addLogEvent(Level level, String text, long duration) {
286         LogEventMark mark = LogEventMark.createFixedLengthEvent(level, text, duration);
287         String text4log = "[Log event](" + duration + "ms) " + text;
288 
289         log(level, text4log, mark);
290     }
291 
292     /**
293      * Add new log event to the log, event won't end, until removed using {@link LogCategory#removeLogEvent(java.lang.Object) }.
294      * @param level level of event.
295      * @param text text of event
296      * @return object that can be later used in {@link LogCategory#removeLogEvent(java.lang.Object)  } in order to remove the event from the log.
297      */
298     public LogEventMark addLogEvent(Level level, String text) {
299         LogEventMark mark = LogEventMark.createVariableLengthEvent(level, text);
300         String text4log = "[Log event](START:" + mark.getId()+ ") " + text;
301 
302         log(level, text4log, mark);
303 
304         return mark;
305     }
306 
307     /**
308      * Remove log event with undefined duration. The event should be created by {@link LogCategory#addLogEvent(java.util.logging.Level, java.lang.String) }
309      * @param mark object returned by {@link LogCategory#addLogEvent(java.util.logging.Level, java.lang.String) }
310      *                     during addition of log event to the log.
311      */
312     public void removeLogEvent(LogEventMark mark) {
313         assert mark!= null;
314 
315         String text4log = "[Log event](END:" + mark.getId() + ") " + mark.getText();
316 
317         log(mark.getLevel(), text4log, mark.getEndMark());
318     }
319 }