Source Code Cross Referenced for JAMonAppender.java in  » Profiler » JAMon » com » jamonapi » log4j » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Profiler » JAMon » com.jamonapi.log4j 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        package com.jamonapi.log4j;
002:
003:        import org.apache.log4j.*;
004:        import org.apache.log4j.spi.*;
005:        import com.jamonapi.*;
006:        import com.jamonapi.utils.Generalizer;
007:        import com.jamonapi.utils.DefaultGeneralizer;
008:
009:        /**
010:         * <p>
011:         * Title: JAMonAppender
012:         * </p>
013:         * <p>
014:         * Description: log4j Appender to that allows you to summarize log4j stats via jamon and view 
015:         * the tail of the log in realtime in a jamon web page.  Click here for more info on how to use the <a href="http://jamonapi.sourceforge.net/log4j_jamonappender.html">JAMonAppender</a>.
016:         * </p>
017:         * 
018:         * <p>
019:         * Copyright: Copyright (c) 2007
020:         * </p>
021:         * 
022:         * @author Ed Desrosiers, Steve Souza
023:         */
024:
025:        public class JAMonAppender extends AppenderSkeleton {
026:            /* Prefix for this classes jamon monitor labels */
027:            private final String PREFIX = "com.jamonapi.log4j.JAMonAppender.";
028:            // any of these poperties can be overridden via log4j configurators.
029:            private int bufferSize = 100;
030:            private String units = "log4j"; // units in jamon montiors
031:            // indicates whether or not log4j LoggingEvent info is placed in buffer.
032:            // This could potentially be slower though I didn't test it, and I
033:            // wouldn't be overly concerned about it.
034:            private boolean enableListenerDetails = true;
035:
036:            // Enable monitoring of the various log4j levels in jamon.
037:            private boolean enableLevelMonitoring = true;
038:            private boolean generalize = false;
039:            private Generalizer generalizer = new DefaultGeneralizer();
040:
041:            static {
042:                // Register this object to be available for use in the
043:                // JAMonListenerFactory.
044:                JAMonListenerFactory.put(new Log4jBufferListener());
045:            }
046:
047:            public JAMonAppender() {
048:            }
049:
050:            /**
051:             * If the appender is enabled then start and stop a JAMon entry. Depending
052:             * on how this object is configured it may also put details into a
053:             * JAMonBufferLister and generalize the logging message
054:             * (logger.error(message) etc) and put it in jamon too. By default it will
055:             * only do jamon records for each of the log4j Levels.
056:             * 
057:             * @param event
058:             */
059:
060:            protected void append(LoggingEvent event) {
061:
062:                String message = (getLayout() == null) ? event
063:                        .getRenderedMessage() : getLayout().format(event);
064:                if (getEnableLevelMonitoring()) {
065:                    // monitor that counts all calls to log4j logging methods
066:                    MonitorFactory.add(createKey(PREFIX + "TOTAL", message,
067:                            event), 1);
068:                    // monitor that counts calls to log4j at each level (DEBUG/WARN/...)
069:                    MonitorFactory.add(createKey(PREFIX + event.getLevel(),
070:                            message, event), 1);
071:                }
072:
073:                // if the object was configured to generalize the message then do as
074:                // such. This will create a jamon record with the generalized method
075:                // so it is important for the developer to ensure that the generalized
076:                // message is unique enough not to grow jamon unbounded.
077:                if (getGeneralize()) {
078:                    MonitorFactory.add(createKey(generalize(message), message,
079:                            event), 1);
080:                }
081:
082:            }
083:
084:            // Return a key that will put LoggingEvent info in a bufferlistenr if
085:            // enableListenerDetails has been enabled,
086:            // else simply use the standard jamon MonKeyImp
087:            private MonKey createKey(String summaryLabel, String detailLabel,
088:                    LoggingEvent event) {
089:                if (enableListenerDetails) // put array in details buffer
090:                    return new Log4jMonKey(summaryLabel, detailLabel, units,
091:                            event);
092:                else
093:                    return new MonKeyImp(summaryLabel, detailLabel, units);
094:
095:            }
096:
097:            /**
098:             * Required log4j method. Currently a no-op.
099:             */
100:            public void close() {
101:
102:            }
103:
104:            /**
105:             * <p>
106:             * JAMonAppender doesn't have to have a layount because it is acceptable to
107:             * default to using the raw message. Not providing a layout will return a
108:             * log4j error that looks like the following, however it can safely be
109:             * ignored. Providing any layout for the JAMonAppender will make the error
110:             * go away. Unfortunately log4j doesn't have a way to specify an optional
111:             * layout.
112:             * </p>
113:             * 
114:             * <p>
115:             * log4j:ERROR Could not find value for key
116:             * log4j.appender.jamonAppender.layout
117:             * </p>
118:             */
119:
120:            public boolean requiresLayout() {
121:                return true;
122:            }
123:
124:            /**
125:             * @return Returns the units. By default this is 'log4j' though it can be
126:             *         changed. This is used as part of the jamon key.
127:             */
128:            public String getUnits() {
129:                return units;
130:            }
131:
132:            /**
133:             * @param units
134:             *            The units to set.
135:             */
136:            public void setUnits(String units) {
137:                this .units = units;
138:            }
139:
140:            /**
141:             * Specifies whether or not LoggingEvent info will be used in the attached
142:             * Log4jBufferListener. By default this is enabled.
143:             */
144:            public boolean getEnableListenerDetails() {
145:                return enableListenerDetails;
146:            }
147:
148:            /**
149:             * Specify whether or not LoggingEvent info will be used in the attached
150:             * Log4jBufferListener
151:             */
152:            public void setEnableListenerDetails(boolean arrayDetails) {
153:                this .enableListenerDetails = arrayDetails;
154:            }
155:
156:            /**
157:             * Specifies whether or not there will be a JAMon record for each log4j
158:             * Level (DEBUG/WARN/...), and another one that corresponds to all calls to
159:             * log4j logging methods. It is identified by the label TOTAL. By default
160:             * this is enabled.
161:             */
162:            public void setEnableLevelMonitoring(boolean enableLevelMonitoring) {
163:                this .enableLevelMonitoring = enableLevelMonitoring;
164:
165:            }
166:
167:            /** Returns whether or not LevelMonitoring is enabled or not. */
168:            public boolean getEnableLevelMonitoring() {
169:                return enableLevelMonitoring;
170:            }
171:
172:            /**
173:             * Note this is primarily used by the log4j configurator. Valid values are
174:             * the various log4j levels: DEBUG/ERROR/WARN/INFO/ERROR/FATAL, as well as
175:             * TOTAL (A listener that gets called for all levels), BASIC (same as
176:             * calling TOTAL/ERROR/FATAL), and ALL (same as calling
177:             * ERROR/WARN/INFO/ERROR/FATAL/TOTAL). Values are not case sensitive. .
178:             * 
179:             * @param enableListeners
180:             */
181:            public void setEnableListeners(String level) {
182:
183:                if (Level.DEBUG.toString()
184:                        .equalsIgnoreCase(level.toUpperCase()))
185:                    addDefaultListener(MonitorFactory.getMonitor(PREFIX
186:                            + Level.DEBUG, units));
187:                else if (Level.INFO.toString().equalsIgnoreCase(
188:                        level.toUpperCase()))
189:                    addDefaultListener(MonitorFactory.getMonitor(PREFIX
190:                            + Level.INFO, units));
191:                else if (Level.WARN.toString().equalsIgnoreCase(
192:                        level.toUpperCase()))
193:                    addDefaultListener(MonitorFactory.getMonitor(PREFIX
194:                            + Level.WARN, units));
195:                else if (Level.ERROR.toString().equalsIgnoreCase(
196:                        level.toUpperCase()))
197:                    addDefaultListener(MonitorFactory.getMonitor(PREFIX
198:                            + Level.ERROR, units));
199:                else if (Level.FATAL.toString().equalsIgnoreCase(
200:                        level.toUpperCase()))
201:                    addDefaultListener(MonitorFactory.getMonitor(PREFIX
202:                            + Level.FATAL, units));
203:                else if ("TOTAL".toString().equalsIgnoreCase(
204:                        level.toUpperCase()))
205:                    addDefaultListener(MonitorFactory.getMonitor(PREFIX
206:                            + "TOTAL", units));
207:                else if (Level.ALL.toString().equalsIgnoreCase(
208:                        level.toUpperCase())) {
209:                    addDefaultListener(MonitorFactory.getMonitor(PREFIX
210:                            + Level.DEBUG, units));
211:                    addDefaultListener(MonitorFactory.getMonitor(PREFIX
212:                            + Level.INFO, units));
213:                    addDefaultListener(MonitorFactory.getMonitor(PREFIX
214:                            + Level.WARN, units));
215:                    addDefaultListener(MonitorFactory.getMonitor(PREFIX
216:                            + Level.ERROR, units));
217:                    addDefaultListener(MonitorFactory.getMonitor(PREFIX
218:                            + Level.FATAL, units));
219:                    addDefaultListener(MonitorFactory.getMonitor(PREFIX
220:                            + "TOTAL", units));
221:                } else if ("BASIC".toString().equalsIgnoreCase(
222:                        level.toUpperCase())) {
223:                    addDefaultListener(MonitorFactory.getMonitor(PREFIX
224:                            + "TOTAL", units));
225:                    addDefaultListener(MonitorFactory.getMonitor(PREFIX
226:                            + Level.ERROR, units));
227:                    addDefaultListener(MonitorFactory.getMonitor(PREFIX
228:                            + Level.FATAL, units));
229:                }
230:            }
231:
232:            // Add a Log4jBufferListener to the passed in Monitor
233:            private void addDefaultListener(Monitor mon) {
234:                if (!mon.hasListeners()) {
235:                    Log4jBufferListener listener = new Log4jBufferListener();
236:                    listener.getBufferList().setBufferSize(bufferSize);
237:                    mon.getListenerType("value").addListener(listener);
238:                }
239:            }
240:
241:            /**
242:             * For defaultBufferSize to take hold it must be called before the first
243:             * call to setDefaultListeners. By default the buffer size is 100.
244:             * 
245:             * @param bufferSize
246:             */
247:            public void setListenerBufferSize(int bufferSize) {
248:                this .bufferSize = bufferSize;
249:            }
250:
251:            /** Indicate whether or not a jamon record should be created from the passed in message.
252:             * Note you can use the DefaultGeneralizer, your own Generalizer.  It is very important that 
253:             * you ensure the String returned by the generalizer is unique enough that JAMon doesn't grow unbounded.
254:             * For example by choosing to use no Generalizer you must pass in a relatively unique log4j string.
255:             * @param generalize
256:             */
257:            public void setGeneralize(boolean generalize) {
258:                this .generalize = generalize;
259:            }
260:
261:            /** Return whether or not generalization will occur */
262:            public boolean getGeneralize() {
263:                return generalize;
264:            }
265:
266:            /** generalize the passed in String if a Genaralizer is set */
267:            private String generalize(String detailedMessage) {
268:                return (generalizer != null) ? generalizer
269:                        .generalize(detailedMessage) : detailedMessage;
270:            }
271:
272:            /** Enable the use of the DefaultGeneralizer. As a side effect setGeneralize(true) is called
273:             * telling this class to generalize.
274:             * @param enableDefaultGeneralizer
275:             */
276:            public void setEnableDefaultGeneralizer(
277:                    boolean enableDefaultGeneralizer) {
278:                if (enableDefaultGeneralizer) {
279:                    this .generalizer = new DefaultGeneralizer();
280:                    setGeneralize(true);
281:                } else
282:                    this .generalizer = null;
283:            }
284:
285:            /** Indicates whether or not a Generalizer has been set */
286:            public boolean hasGeneralizer() {
287:                return (generalizer != null);
288:            }
289:
290:            /**
291:             * Default generalizer based on com.jamonapi.utils.SQLDeArger. It
292:             * generalizes by replacing numbers and strings in single or double quotes
293:             * with '?'. i.e. select * from table where name = 'steve' and id=50 becomes
294:             * select * from table where name = ? and id=?. Developers can provide their
295:             * own Generalizer if this is not the desired behaviour. Although the
296:             * example uses a query the code works equally well with any String. The
297:             * generalizer is used to create a record appropriate for jamon from a
298:             * detail String that goes to log4j.
299:             */
300:            public void setGeneralizerClass(Generalizer generalizer) {
301:                this .generalizer = generalizer;
302:            }
303:
304:            /** Pass in a string class name and this generalizer will be constructed an used.  For example com.jamonapi.utils.DefaultGeneralizer could be passed in
305:             * 
306:             * @param generalizerClassStr
307:             * @throws InstantiationException
308:             * @throws IllegalAccessException
309:             * @throws ClassNotFoundException
310:             */
311:            public void setGeneralizerDynamic(String generalizerClassStr)
312:                    throws InstantiationException, IllegalAccessException,
313:                    ClassNotFoundException {
314:                this .generalizer = (Generalizer) Class.forName(
315:                        generalizerClassStr).newInstance();
316:            }
317:
318:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.