1 package org.apache.turbine.services.logging.jdbc;
2
3 /* ====================================================================
4 * The Apache Software License, Version 1.1
5 *
6 * Copyright (c) 2001 The Apache Software Foundation. All rights
7 * reserved.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
11 * are met:
12 *
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 *
16 * 2. Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in
18 * the documentation and/or other materials provided with the
19 * distribution.
20 *
21 * 3. The end-user documentation included with the redistribution,
22 * if any, must include the following acknowledgment:
23 * "This product includes software developed by the
24 * Apache Software Foundation (http://www.apache.org/)."
25 * Alternately, this acknowledgment may appear in the software itself,
26 * if and wherever such third-party acknowledgments normally appear.
27 *
28 * 4. The names "Apache" and "Apache Software Foundation" and
29 * "Apache Turbine" must not be used to endorse or promote products
30 * derived from this software without prior written permission. For
31 * written permission, please contact apache@apache.org.
32 *
33 * 5. Products derived from this software may not be called "Apache",
34 * "Apache Turbine", nor may "Apache" appear in their name, without
35 * prior written permission of the Apache Software Foundation.
36 *
37 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
38 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
39 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
40 * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
41 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
42 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
43 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
44 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
45 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
46 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
47 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
48 * SUCH DAMAGE.
49 * ====================================================================
50 *
51 * This software consists of voluntary contributions made by many
52 * individuals on behalf of the Apache Software Foundation. For more
53 * information on the Apache Software Foundation, please see
54 * <http://www.apache.org/>.
55 */
56
57 import java.util.ArrayList;
58 import java.util.Hashtable;
59 import org.apache.log4j.AppenderSkeleton;
60 import org.apache.log4j.spi.LoggingEvent;
61
62 /***
63 * The JDBCAppender, writes messages into a database.
64 *
65 * The JDBCAppender is configurable at runtime by setting options in
66 * two alternatives :
67 *
68 * @author <a href="mailto:t.fenner@klopotek.de">Thomas Fenner</a>
69 * @author <a href="mailto:jvanzyl@periapt.com">Jason van Zyl</a>
70 */
71 public class JDBCAppender extends AppenderSkeleton
72 {
73 /***
74 * Logger class option.
75 */
76 public static final String LOGGER_CLASS_OPTION = "logger.class";
77
78 /***
79 * An option to set for the logger, these are name:value pairs
80 * that are used to initialize a logger.
81 */
82 public static final String LOGGER_OPTION = "logger.option";
83
84 /***
85 * Logger class to instantiate for logging to
86 * a database.
87 */
88 private String loggerClass = null;
89
90 /***
91 * Hashtable of options that are used to initialize
92 * the logger being used.
93 */
94 private Hashtable loggerOptions = new Hashtable();
95
96 /*
97 * This class encapsulate the logic which is necessary
98 * to log into a table.
99 */
100 private JDBCLogger logger = null;
101
102 /***
103 * Hold bin for messages that need to be pushed into
104 * the database into which we are logging.
105 */
106 private ArrayList buffer = new ArrayList();
107
108 /***
109 * How many messages should we buffer until to
110 * push the messages into the database.
111 */
112 private int bufferSize = 1;
113
114 /*
115 * A flag to indicate that everything is ready to
116 * get append() commands.
117 */
118 private boolean ready = false;
119
120 /***
121 * If program terminates close the database-connection and
122 * flush the buffer.
123 */
124 public void finalize()
125 {
126 close();
127 super.finalize();
128 }
129
130 /***
131 * Internal method. Returns a array of strings containing the available
132 * options which can be set with method setOption()
133 */
134 public String[] getOptionStrings()
135 {
136 /*
137 * The sequence of options in this string is important, because
138 * setOption() is called this way ...
139 */
140 return new String[]
141 {
142 LOGGER_CLASS_OPTION,
143 LOGGER_OPTION
144 };
145 }
146
147 /***
148 * Sets all necessary options
149 *
150 * @param String option
151 * @param String value
152 */
153 public void setOption(String option, String value)
154 {
155 option = option.trim();
156 value = value.trim();
157
158 if (option == null || value == null)
159 {
160 return;
161 }
162 if (option.length() == 0 || value.length() == 0)
163 {
164 return;
165 }
166
167 value = value.trim();
168
169 if (option.equals(LOGGER_CLASS_OPTION))
170 {
171 loggerClass = value;
172 }
173 else if (option.equals(LOGGER_CLASS_OPTION))
174 {
175 String loggerOptionKey = value.substring(0,value.indexOf(":") - 1);
176 String loggerOptionValue = value.substring(value.indexOf(":"));
177 loggerOptions.put(loggerOptionKey, loggerOptionValue);
178 }
179 }
180
181 /***
182 * Active our logger to be used for appending messages
183 * to the database.
184 */
185 public void activateOptions()
186 {
187 /*
188 * Set up the logger.
189 */
190 try
191 {
192 logger = (JDBCLogger) Class.forName(loggerClass).newInstance();
193 logger.init(loggerOptions);
194 }
195 catch (Exception e)
196 {
197 e.printStackTrace();
198 }
199 }
200
201 /***
202 * Internal method. Returns true, you may define
203 * your own layout...
204 *
205 * @return boolean
206 */
207 public boolean requiresLayout()
208 {
209 return true;
210 }
211
212 /***
213 * Internal method. Close the database connection & flush the buffer.
214 */
215 public void close()
216 {
217 flushBuffer();
218 logger.close();
219 closed = true;
220 }
221
222 /***
223 * Internal method. Appends the message to the database table.
224 *
225 * @param LoggingEvent event
226 */
227 public void append(LoggingEvent event)
228 {
229 if (!ready)
230 {
231 if (!isReady())
232 {
233 errorHandler.error("Not ready to append!");
234 return;
235 }
236 }
237
238 buffer.add(event);
239
240 if (buffer.size() >= bufferSize)
241 {
242 flushBuffer();
243 }
244 }
245
246
247 /***
248 * Internal method. Flushes the buffer.
249 */
250 public void flushBuffer()
251 {
252 try
253 {
254 int size = buffer.size();
255
256 if (size < 1)
257 {
258 return;
259 }
260
261 for (int i = 0; i < size; i++)
262 {
263 LoggingEvent event = (LoggingEvent) buffer.get(i);
264
265 /*
266 * Insert message into database
267 */
268 logger.append(layout.format(event));
269 }
270
271 buffer.clear();
272 }
273 catch (Exception e)
274 {
275 errorHandler.error(
276 "JDBCAppender.flushBuffer(), " + e + " : " +
277 logger.getErrorMsg());
278
279 return;
280 }
281 }
282
283 /***
284 * Internal method. Returns true, when the JDBCAppender is ready to
285 * append messages to the database, else false.
286 *
287 * @return boolean
288 */
289 public boolean isReady()
290 {
291 if (ready)
292 {
293 return true;
294 }
295
296 ready = logger.isReady();
297
298 if (!ready)
299 {
300 errorHandler.error(logger.getErrorMsg());
301 }
302
303 return ready;
304 }
305 }
This page was automatically generated by Maven