pax_global_header 0000666 0000000 0000000 00000000064 12527427642 0014525 g ustar 00root root 0000000 0000000 52 comment=39cc12afcca44575ba6f0689b92f66e777adc574
apache-log4j-extras1.2-1.2.17/ 0000775 0000000 0000000 00000000000 12527427642 0015600 5 ustar 00root root 0000000 0000000 apache-log4j-extras1.2-1.2.17/LICENSE 0000664 0000000 0000000 00000026146 12527427642 0016616 0 ustar 00root root 0000000 0000000
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright 1999-2005 The Apache Software Foundation
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
apache-log4j-extras1.2-1.2.17/NOTICE 0000664 0000000 0000000 00000000273 12527427642 0016506 0 ustar 00root root 0000000 0000000 Apache Extras Companion for log4j 1.2.
Copyright 2010 The Apache Software Foundation
This product includes software developed at
The Apache Software Foundation (http://www.apache.org/).
apache-log4j-extras1.2-1.2.17/pom.xml 0000664 0000000 0000000 00000033402 12527427642 0017117 0 ustar 00root root 0000000 0000000
Apache Extras for Apache log4j, Apache log4j and Apache are trademarks of the Apache Software Foundation.
]]>* If the JDBC driver you are using supports the * {@link java.sql.Statement#getGeneratedKeys}method introduced in JDBC 3.0 * specification, then you are all set. Otherwise, there must be an * {@link SQLDialect}appropriate for your database system. Currently, we have * dialects for PostgreSQL, MySQL, Oracle and MsSQL. As mentioed previously, an * SQLDialect is required only if the JDBC driver for your database system does * not support the {@link java.sql.Statement#getGeneratedKeys getGeneratedKeys} * method. *
* *RDBMS | *supports getGeneratedKeys() method |
* specific SQLDialect support |
*
---|---|---|
PostgreSQL | *NO | *present and used | *
MySQL | *YES | *present, but not actually needed or used | *
Oracle | *YES | *present, but not actually needed or used | *
DB2 | *YES | *not present, and not needed or used | *
MsSQL | *YES | *not present, and not needed or used | *
HSQL | *NO | *present and used | *
* Performance: Experiments show that writing a single event into the * database takes approximately 50 milliseconds, on a "standard" PC. If pooled * connections are used, this figure drops to under 10 milliseconds. Note that * most JDBC drivers already ship with connection pooling support. *
* * * *
* Configuration DBAppender can be configured programmatically, or using
* {@link org.apache.log4j.xml.DOMConfigurator JoranConfigurator}. Example
* scripts can be found in the tests/input/db directory.
*
* @author Ceki Gülcü
* @author Ray DeCampo
*/
public class DBAppender extends AppenderSkeleton implements UnrecognizedElementHandler {
static final String insertPropertiesSQL =
"INSERT INTO logging_event_property (event_id, mapped_key, mapped_value) VALUES (?, ?, ?)";
static final String insertExceptionSQL =
"INSERT INTO logging_event_exception (event_id, i, trace_line) VALUES (?, ?, ?)";
static final String insertSQL;
private static final Method GET_GENERATED_KEYS_METHOD;
static {
StringBuffer sql = new StringBuffer();
sql.append("INSERT INTO logging_event (");
sql.append("sequence_number, ");
sql.append("timestamp, ");
sql.append("rendered_message, ");
sql.append("logger_name, ");
sql.append("level_string, ");
sql.append("ndc, ");
sql.append("thread_name, ");
sql.append("reference_flag, ");
sql.append("caller_filename, ");
sql.append("caller_class, ");
sql.append("caller_method, ");
sql.append("caller_line) ");
sql.append(" VALUES (?, ?, ? ,?, ?, ?, ?, ?, ?, ?, ?, ?)");
insertSQL = sql.toString();
//
// PreparedStatement.getGeneratedKeys added in JDK 1.4
//
Method getGeneratedKeysMethod;
try {
getGeneratedKeysMethod = PreparedStatement.class.getMethod("getGeneratedKeys", null);
} catch(Exception ex) {
getGeneratedKeysMethod = null;
}
GET_GENERATED_KEYS_METHOD = getGeneratedKeysMethod;
}
ConnectionSource connectionSource;
boolean cnxSupportsGetGeneratedKeys = false;
boolean cnxSupportsBatchUpdates = false;
SQLDialect sqlDialect;
boolean locationInfo = false;
public DBAppender() {
super(false);
}
public void activateOptions() {
LogLog.debug("DBAppender.activateOptions called");
if (connectionSource == null) {
throw new IllegalStateException(
"DBAppender cannot function without a connection source");
}
sqlDialect = Util.getDialectFromCode(connectionSource.getSQLDialectCode());
if (GET_GENERATED_KEYS_METHOD != null) {
cnxSupportsGetGeneratedKeys = connectionSource.supportsGetGeneratedKeys();
} else {
cnxSupportsGetGeneratedKeys = false;
}
cnxSupportsBatchUpdates = connectionSource.supportsBatchUpdates();
if (!cnxSupportsGetGeneratedKeys && (sqlDialect == null)) {
throw new IllegalStateException(
"DBAppender cannot function if the JDBC driver does not support getGeneratedKeys method *and* without a specific SQL dialect");
}
// all nice and dandy on the eastern front
super.activateOptions();
}
/**
* @return Returns the connectionSource.
*/
public ConnectionSource getConnectionSource() {
return connectionSource;
}
/**
* @param connectionSource
* The connectionSource to set.
*/
public void setConnectionSource(ConnectionSource connectionSource) {
LogLog.debug("setConnectionSource called for DBAppender");
this.connectionSource = connectionSource;
}
protected void append(LoggingEvent event) {
Connection connection = null;
try {
connection = connectionSource.getConnection();
connection.setAutoCommit(false);
PreparedStatement insertStatement;
if (cnxSupportsGetGeneratedKeys) {
insertStatement = connection.prepareStatement(insertSQL, Statement.RETURN_GENERATED_KEYS);
} else {
insertStatement = connection.prepareStatement(insertSQL);
}
/* insertStatement.setLong(1, event.getSequenceNumber());*/
insertStatement.setLong(1, 0);
insertStatement.setLong(2, event.getTimeStamp());
insertStatement.setString(3, event.getRenderedMessage());
insertStatement.setString(4, event.getLoggerName());
insertStatement.setString(5, event.getLevel().toString());
insertStatement.setString(6, event.getNDC());
insertStatement.setString(7, event.getThreadName());
insertStatement.setShort(8, DBHelper.computeReferenceMask(event));
LocationInfo li;
if (event.locationInformationExists() || locationInfo) {
li = event.getLocationInformation();
} else {
li = LocationInfo.NA_LOCATION_INFO;
}
insertStatement.setString(9, li.getFileName());
insertStatement.setString(10, li.getClassName());
insertStatement.setString(11, li.getMethodName());
insertStatement.setString(12, li.getLineNumber());
int updateCount = insertStatement.executeUpdate();
if (updateCount != 1) {
LogLog.warn("Failed to insert loggingEvent");
}
ResultSet rs = null;
Statement idStatement = null;
boolean gotGeneratedKeys = false;
if (cnxSupportsGetGeneratedKeys) {
try {
rs = (ResultSet) GET_GENERATED_KEYS_METHOD.invoke(insertStatement, null);
gotGeneratedKeys = true;
} catch(InvocationTargetException ex) {
Throwable target = ex.getTargetException();
if (target instanceof SQLException) {
throw (SQLException) target;
}
throw ex;
} catch(IllegalAccessException ex) {
LogLog.warn("IllegalAccessException invoking PreparedStatement.getGeneratedKeys", ex);
}
}
if (!gotGeneratedKeys) {
insertStatement.close();
insertStatement = null;
idStatement = connection.createStatement();
idStatement.setMaxRows(1);
rs = idStatement.executeQuery(sqlDialect.getSelectInsertId());
}
// A ResultSet cursor is initially positioned before the first row; the
// first call to the method next makes the first row the current row
rs.next();
int eventId = rs.getInt(1);
rs.close();
// we no longer need the insertStatement
if(insertStatement != null) {
insertStatement.close();
insertStatement = null;
}
if(idStatement != null) {
idStatement.close();
idStatement = null;
}
Set propertiesKeys = event.getPropertyKeySet();
if (propertiesKeys.size() > 0) {
PreparedStatement insertPropertiesStatement =
connection.prepareStatement(insertPropertiesSQL);
for (Iterator i = propertiesKeys.iterator(); i.hasNext();) {
String key = (String) i.next();
String value = event.getProperty(key);
//LogLog.info("id " + eventId + ", key " + key + ", value " + value);
insertPropertiesStatement.setInt(1, eventId);
insertPropertiesStatement.setString(2, key);
insertPropertiesStatement.setString(3, value);
if (cnxSupportsBatchUpdates) {
insertPropertiesStatement.addBatch();
} else {
insertPropertiesStatement.execute();
}
}
if (cnxSupportsBatchUpdates) {
insertPropertiesStatement.executeBatch();
}
insertPropertiesStatement.close();
insertPropertiesStatement = null;
}
String[] strRep = event.getThrowableStrRep();
if (strRep != null) {
LogLog.debug("Logging an exception");
PreparedStatement insertExceptionStatement =
connection.prepareStatement(insertExceptionSQL);
for (short i = 0; i < strRep.length; i++) {
insertExceptionStatement.setInt(1, eventId);
insertExceptionStatement.setShort(2, i);
insertExceptionStatement.setString(3, strRep[i]);
if (cnxSupportsBatchUpdates) {
insertExceptionStatement.addBatch();
} else {
insertExceptionStatement.execute();
}
}
if (cnxSupportsBatchUpdates) {
insertExceptionStatement.executeBatch();
}
insertExceptionStatement.close();
insertExceptionStatement = null;
}
connection.commit();
} catch (Throwable sqle) {
LogLog.error("problem appending event", sqle);
} finally {
DBHelper.closeConnection(connection);
}
}
public void close() {
closed = true;
}
/**
* Returns value of the LocationInfo property which determines whether
* caller's location info is written to the database.
*/
public boolean getLocationInfo() {
return locationInfo;
}
/**
* If true, the information written to the database will include caller's
* location information. Due to performance concerns, by default no location
* information is written to the database.
*/
public void setLocationInfo(boolean locationInfo) {
this.locationInfo = locationInfo;
}
/**
* Gets whether appender requires a layout.
* @return false
*/
public boolean requiresLayout() {
return false;
}
/**
* {@inheritDoc}
*/
public boolean parseUnrecognizedElement(Element element, Properties props) throws Exception {
if ("connectionSource".equals(element.getNodeName())) {
Object instance =
DOMConfigurator.parseElement(element, props, ConnectionSource.class);
if (instance instanceof ConnectionSource) {
ConnectionSource source = (ConnectionSource) instance;
source.activateOptions();
setConnectionSource(source);
}
return true;
}
return false;
}
}
apache-log4j-extras1.2-1.2.17/src/main/java/org/apache/log4j/LoggerRepositoryExImpl.java 0000664 0000000 0000000 00000046576 12527427642 0030606 0 ustar 00root root 0000000 0000000 /*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.log4j;
import org.apache.log4j.component.plugins.Plugin;
import org.apache.log4j.component.plugins.PluginRegistry;
import org.apache.log4j.component.scheduler.Scheduler;
import org.apache.log4j.component.spi.ErrorItem;
import org.apache.log4j.component.spi.LoggerEventListener;
import org.apache.log4j.component.spi.LoggerRepositoryEventListener;
import org.apache.log4j.component.spi.LoggerRepositoryEx;
import org.apache.log4j.helpers.LogLog;
import org.apache.log4j.or.ObjectRenderer;
import org.apache.log4j.or.RendererMap;
import org.apache.log4j.spi.HierarchyEventListener;
import org.apache.log4j.spi.LoggerFactory;
import org.apache.log4j.spi.LoggerRepository;
import org.apache.log4j.spi.RendererSupport;
import org.apache.log4j.xml.DOMConfigurator;
import org.apache.log4j.xml.UnrecognizedElementHandler;
import org.w3c.dom.Element;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Vector;
/**
* This class implements LoggerRepositoryEx by
* wrapping an existing LoggerRepository implementation
* and implementing the newly added capabilities.
*/
public final class LoggerRepositoryExImpl
implements LoggerRepositoryEx,
RendererSupport,
UnrecognizedElementHandler {
/**
* Wrapped logger repository.
*/
private final LoggerRepository repo;
/**
* Logger factory. Does not affect class of logger
* created by underlying repository.
*/
private LoggerFactory loggerFactory;
/**
* Renderer support.
*/
private final RendererSupport rendererSupport;
/**
* List of repository event listeners.
*/
private final ArrayList repositoryEventListeners = new ArrayList();
/**
* Map of HierarchyEventListener keyed by LoggingEventListener.
*/
private final Map loggerEventListeners = new HashMap();
/**
* Name of hierarchy.
*/
private String name;
/**
* Plug in registry.
*/
private PluginRegistry pluginRegistry;
/**
* Properties.
*/
private final Map properties = new Hashtable();
/**
* Scheduler.
*/
private Scheduler scheduler;
/** The repository can also be used as an object store
* for various objects used by log4j components.
*/
private Map objectMap = new HashMap();
/**
* Error list.
*/
private List errorList = new Vector();
/**
* True if hierarchy has not been modified.
*/
private boolean pristine = true;
/**
Constructs a new logger hierarchy.
@param repository Base implementation of repository.
*/
public LoggerRepositoryExImpl(final LoggerRepository repository) {
super();
if (repository == null) {
throw new NullPointerException("repository");
}
repo = repository;
if (repository instanceof RendererSupport) {
rendererSupport = (RendererSupport) repository;
} else {
rendererSupport = new RendererSupportImpl();
}
}
/**
Add a {@link LoggerRepositoryEventListener} to the repository. The
listener will be called when repository events occur.
@param listener listener
*/
public void addLoggerRepositoryEventListener(
final LoggerRepositoryEventListener listener) {
synchronized (repositoryEventListeners) {
if (repositoryEventListeners.contains(listener)) {
LogLog.warn(
"Ignoring attempt to add a previously "
+ "registered LoggerRepositoryEventListener.");
} else {
repositoryEventListeners.add(listener);
}
}
}
/**
Remove a {@link LoggerRepositoryEventListener} from the repository.
@param listener listener
*/
public void removeLoggerRepositoryEventListener(
final LoggerRepositoryEventListener listener) {
synchronized (repositoryEventListeners) {
if (!repositoryEventListeners.contains(listener)) {
LogLog.warn(
"Ignoring attempt to remove a "
+ "non-registered LoggerRepositoryEventListener.");
} else {
repositoryEventListeners.remove(listener);
}
}
}
/**
Add a {@link LoggerEventListener} to the repository. The listener
will be called when repository events occur.
@param listener listener
*/
public void addLoggerEventListener(final LoggerEventListener listener) {
synchronized (loggerEventListeners) {
if (loggerEventListeners.get(listener) != null) {
LogLog.warn(
"Ignoring attempt to add a previously registerd LoggerEventListener.");
} else {
HierarchyEventListenerProxy proxy =
new HierarchyEventListenerProxy(listener);
loggerEventListeners.put(listener, proxy);
repo.addHierarchyEventListener(proxy);
}
}
}
/**
Add a {@link org.apache.log4j.spi.HierarchyEventListener}
event to the repository.
@param listener listener
@deprecated Superceded by addLoggerEventListener
*/
public
void addHierarchyEventListener(final HierarchyEventListener listener) {
repo.addHierarchyEventListener(listener);
}
/**
Remove a {@link LoggerEventListener} from the repository.
@param listener listener to be removed
*/
public void removeLoggerEventListener(final LoggerEventListener listener) {
synchronized (loggerEventListeners) {
HierarchyEventListenerProxy proxy =
(HierarchyEventListenerProxy) loggerEventListeners.get(listener);
if (proxy == null) {
LogLog.warn(
"Ignoring attempt to remove a non-registered LoggerEventListener.");
} else {
loggerEventListeners.remove(listener);
proxy.disable();
}
}
}
/**
* Issue warning that there are no appenders in hierarchy.
* @param cat logger, not currently used.
*/
public void emitNoAppenderWarning(final Category cat) {
repo.emitNoAppenderWarning(cat);
}
/**
Check if the named logger exists in the hierarchy. If so return
its reference, otherwise returns null
.
@param loggerName The name of the logger to search for.
@return true if logger exists.
*/
public Logger exists(final String loggerName) {
return repo.exists(loggerName);
}
/**
* Return the name of this hierarchy.
* @return name of hierarchy
*/
public String getName() {
return name;
}
/**
* Set the name of this repository.
*
* Note that once named, a repository cannot be rerenamed.
* @param repoName name of hierarchy
*/
public void setName(final String repoName) {
if (name == null) {
name = repoName;
} else if (!name.equals(repoName)) {
throw new IllegalStateException(
"Repository [" + name + "] cannot be renamed as [" + repoName + "].");
}
}
/**
* {@inheritDoc}
*/
public Map getProperties() {
return properties;
}
/**
* {@inheritDoc}
*/
public String getProperty(final String key) {
return (String) properties.get(key);
}
/**
* Set a property by key and value. The property will be shared by all
* events in this repository.
* @param key property name
* @param value property value
*/
public void setProperty(final String key,
final String value) {
properties.put(key, value);
}
/**
The string form of {@link #setThreshold(Level)}.
@param levelStr symbolic name for level
*/
public void setThreshold(final String levelStr) {
repo.setThreshold(levelStr);
}
/**
Enable logging for logging requests with level l
or
higher. By default all levels are enabled.
@param l The minimum level for which logging requests are sent to
their appenders. */
public void setThreshold(final Level l) {
repo.setThreshold(l);
}
/**
* {@inheritDoc}
*/
public PluginRegistry getPluginRegistry() {
if (pluginRegistry == null) {
pluginRegistry = new PluginRegistry(this);
}
return pluginRegistry;
}
/**
Requests that a appender added event be sent to any registered
{@link LoggerEventListener}.
@param logger The logger to which the appender was added.
@param appender The appender added to the logger.
*/
public void fireAddAppenderEvent(final Category logger,
final Appender appender) {
repo.fireAddAppenderEvent(logger, appender);
}
/**
Requests that a appender removed event be sent to any registered
{@link LoggerEventListener}.
@param logger The logger from which the appender was removed.
@param appender The appender removed from the logger.
*/
public void fireRemoveAppenderEvent(final Category logger,
final Appender appender) {
if (repo instanceof Hierarchy) {
((Hierarchy) repo).fireRemoveAppenderEvent(logger, appender);
}
}
/**
Requests that a level changed event be sent to any registered
{@link LoggerEventListener}.
@param logger The logger which changed levels.
*/
public void fireLevelChangedEvent(final Logger logger) {
}
/**
*
* Requests that a configuration changed event be sent to any registered
* {@link LoggerRepositoryEventListener}.
*
*/
public void fireConfigurationChangedEvent() {
}
/**
Returns the current threshold.
@return current threshold level
@since 1.2 */
public Level getThreshold() {
return repo.getThreshold();
}
/**
Return a new logger instance named as the first parameter using
the default factory.
If a logger of that name already exists, then it will be
returned. Otherwise, a new logger will be instantiated and
then linked with its existing ancestors as well as children.
@param loggerName The name of the logger to retrieve.
@return logger
*/
public Logger getLogger(final String loggerName) {
return repo.getLogger(loggerName);
}
/**
Return a new logger instance named as the first parameter using
factory
.
If a logger of that name already exists, then it will be
returned. Otherwise, a new logger will be instantiated by the
factory
parameter and linked with its existing
ancestors as well as children.
@param loggerName The name of the logger to retrieve.
@param factory The factory that will make the new logger instance.
@return logger
*/
public Logger getLogger(final String loggerName,
final LoggerFactory factory) {
return repo.getLogger(loggerName, factory);
}
/**
Returns all the currently defined categories in this hierarchy as
an {@link java.util.Enumeration Enumeration}.
The root logger is not included in the returned
{@link Enumeration}.
@return enumerator of current loggers
*/
public Enumeration getCurrentLoggers() {
return repo.getCurrentLoggers();
}
/**
* Return the the list of previously encoutered {@link org.apache.log4j.component.spi.ErrorItem error items}.
* @return list of errors
*/
public List getErrorList() {
return errorList;
}
/**
* Add an error item to the list of previously encountered errors.
* @param errorItem error to add to list of errors.
*/
public void addErrorItem(final ErrorItem errorItem) {
getErrorList().add(errorItem);
}
/**
* Get enumerator over current loggers.
* @return enumerator over current loggers
@deprecated Please use {@link #getCurrentLoggers} instead.
*/
public Enumeration getCurrentCategories() {
return repo.getCurrentCategories();
}
/**
Get the renderer map for this hierarchy.
@return renderer map
*/
public RendererMap getRendererMap() {
return rendererSupport.getRendererMap();
}
/**
Get the root of this hierarchy.
@since 0.9.0
@return root of hierarchy
*/
public Logger getRootLogger() {
return repo.getRootLogger();
}
/**
This method will return true
if this repository is
disabled for level
value passed as parameter and
false
otherwise. See also the {@link
#setThreshold(Level) threshold} method.
@param level numeric value for level.
@return true if disabled for specified level
*/
public boolean isDisabled(final int level) {
return repo.isDisabled(level);
}
/**
Reset all values contained in this hierarchy instance to their
default. This removes all appenders from all categories, sets
the level of all non-root categories to null
,
sets their additivity flag to true
and sets the level
of the root logger to DEBUG. Moreover,
message disabling is set its default "off" value.
Existing categories are not removed. They are just reset.
This method should be used sparingly and with care as it will block all logging until it is completed.
@since 0.8.5 */ public void resetConfiguration() { repo.resetConfiguration(); } /** Used by subclasses to add a renderer to the hierarchy passed as parameter. @param renderedClass class @param renderer object used to render class. */ public void setRenderer(final Class renderedClass, final ObjectRenderer renderer) { rendererSupport.setRenderer(renderedClass, renderer); } /** * {@inheritDoc} */ public boolean isPristine() { return pristine; } /** * {@inheritDoc} */ public void setPristine(final boolean state) { pristine = state; } /** Shutting down a hierarchy will safely close and remove all appenders in all categories including the root logger.Some appenders such as org.apache.log4j.net.SocketAppender and AsyncAppender need to be closed before the application exists. Otherwise, pending logging events might be lost.
The shutdown
method is careful to close nested
appenders before closing regular appenders. This is allows
configurations where a regular appender is attached to a logger
and again to a nested appender.
@since 1.0 */
public void shutdown() {
repo.shutdown();
}
/**
* Return this repository's own scheduler.
* The scheduler is lazily instantiated.
* @return this repository's own scheduler.
*/
public Scheduler getScheduler() {
if (scheduler == null) {
scheduler = new Scheduler();
scheduler.setDaemon(true);
scheduler.start();
}
return scheduler;
}
/**
* Puts object by key.
* @param key key, may not be null.
* @param value object to associate with key.
*/
public void putObject(final String key,
final Object value) {
objectMap.put(key, value);
}
/**
* Get object by key.
* @param key key, may not be null.
* @return object associated with key or null.
*/
public Object getObject(final String key) {
return objectMap.get(key);
}
/**
* Set logger factory.
* @param factory logger factory.
*/
public void setLoggerFactory(final LoggerFactory factory) {
if (factory == null) {
throw new NullPointerException();
}
this.loggerFactory = factory;
}
/**
* Get logger factory.
* @return logger factory.
*/
public LoggerFactory getLoggerFactory() {
return loggerFactory;
}
/** {@inheritDoc} */
public boolean parseUnrecognizedElement(
final Element element,
final Properties props) throws Exception {
if ("plugin".equals(element.getNodeName())) {
Object instance =
DOMConfigurator.parseElement(element, props, Plugin.class);
if (instance instanceof Plugin) {
Plugin plugin = (Plugin) instance;
String pluginName = DOMConfigurator.subst(element.getAttribute("name"), props);
if (pluginName.length() > 0) {
plugin.setName(pluginName);
}
getPluginRegistry().addPlugin(plugin);
plugin.setLoggerRepository(this);
LogLog.debug("Pushing plugin on to the object stack.");
plugin.activateOptions();
return true;
}
}
return false;
}
/**
* Implementation of RendererSupportImpl if not
* provided by LoggerRepository.
*/
private static final class RendererSupportImpl implements RendererSupport {
/**
* Renderer map.
*/
private final RendererMap renderers = new RendererMap();
/**
* Create new instance.
*/
public RendererSupportImpl() {
super();
}
/** {@inheritDoc} */
public RendererMap getRendererMap() {
return renderers;
}
/** {@inheritDoc} */
public void setRenderer(final Class renderedClass,
final ObjectRenderer renderer) {
renderers.put(renderedClass, renderer);
}
}
/**
* Proxy that implements HierarchyEventListener
* and delegates to LoggerEventListener.
*/
private static final class HierarchyEventListenerProxy
implements HierarchyEventListener {
/**
* Wrapper listener.
*/
private LoggerEventListener listener;
/**
* Creates new instance.
* @param l listener
*/
public HierarchyEventListenerProxy(final LoggerEventListener l) {
super();
if (l == null) {
throw new NullPointerException("l");
}
listener = l;
}
/** {@inheritDoc} */
public void addAppenderEvent(final Category cat,
final Appender appender) {
if (isEnabled() && cat instanceof Logger) {
listener.appenderAddedEvent((Logger) cat, appender);
}
}
/** {@inheritDoc} */
public void removeAppenderEvent(final Category cat,
final Appender appender) {
if (isEnabled() && cat instanceof Logger) {
listener.appenderRemovedEvent((Logger) cat, appender);
}
}
/**
* Disable forwarding of notifications to
* simulate removal of listener.
*/
public synchronized void disable() {
listener = null;
}
/**
* Gets whether proxy is enabled.
* @return true if proxy is enabled.
*/
private synchronized boolean isEnabled() {
return listener != null;
}
}
}
apache-log4j-extras1.2-1.2.17/src/main/java/org/apache/log4j/component/ 0000775 0000000 0000000 00000000000 12527427642 0025265 5 ustar 00root root 0000000 0000000 apache-log4j-extras1.2-1.2.17/src/main/java/org/apache/log4j/component/ULogger.java 0000664 0000000 0000000 00000015360 12527427642 0027501 0 ustar 00root root 0000000 0000000 /*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.log4j.component;
/**
* A proxy for org.slf4j.ULogger. In slf4j implementing builds, this
* interface will extend org.slf4j.ULogger and add no additional methods.
*
* @author Ceki Gülcü
* @author Curt Arnold
*/
public interface ULogger {
/**
* Is the logger instance enabled for the DEBUG level?
* @return true if debug is enabled.
*/
boolean isDebugEnabled();
/**
* Log a message object with the DEBUG level.
* @param msg - the message object to be logged
*/
void debug(Object msg);
/**
* Log a parameterized message object at the DEBUG level.
*
*
This form is useful in avoiding the superflous object creation * problem when invoking this method while it is disabled. *
* @param parameterizedMsg - the parameterized message object * @param param1 - the parameter */ void debug(Object parameterizedMsg, Object param1); /** * Log a parameterized message object at the DEBUG level. * *This form is useful in avoiding the superflous object creation * problem when invoking this method while it is disabled. *
* @param parameterizedMsg - the parameterized message object * @param param1 - the first parameter * @param param2 - the second parameter */ void debug(String parameterizedMsg, Object param1, Object param2); /** * Log a message object with theDEBUG
level including the
* stack trace of the {@link Throwable}t
passed as parameter.
*
*
* @param msg the message object to log.
* @param t the exception to log, including its stack trace.
*/
void debug(Object msg, Throwable t);
/**
* Is the logger instance enabled for the INFO level?
* @return true if debug is enabled.
*/
boolean isInfoEnabled();
/**
* Log a message object with the INFO level.
* @param msg - the message object to be logged
*/
void info(Object msg);
/**
* Log a parameterized message object at the INFO level.
*
* This form is useful in avoiding the superflous object creation * problem when invoking this method while it is disabled. *
* @param parameterizedMsg - the parameterized message object * @param param1 - the parameter */ void info(Object parameterizedMsg, Object param1); /** * Log a parameterized message object at the INFO level. * *This form is useful in avoiding the superflous object creation * problem when invoking this method while it is disabled. *
* @param parameterizedMsg - the parameterized message object * @param param1 - the first parameter * @param param2 - the second parameter */ void info(String parameterizedMsg, Object param1, Object param2); /** * Log a message object with theINFO
level including the
* stack trace of the {@link Throwable}t
passed as parameter.
*
*
* @param msg the message object to log.
* @param t the exception to log, including its stack trace.
*/
void info(Object msg, Throwable t);
/**
* Is the logger instance enabled for the WARN level?
* @return true if debug is enabled.
*/
boolean isWarnEnabled();
/**
* Log a message object with the WARN level.
* @param msg - the message object to be logged
*/
void warn(Object msg);
/**
* Log a parameterized message object at the WARN level.
*
* This form is useful in avoiding the superflous object creation * problem when invoking this method while it is disabled. *
* @param parameterizedMsg - the parameterized message object * @param param1 - the parameter */ void warn(Object parameterizedMsg, Object param1); /** * Log a parameterized message object at the WARN level. * *This form is useful in avoiding the superflous object creation * problem when invoking this method while it is disabled. *
* @param parameterizedMsg - the parameterized message object * @param param1 - the first parameter * @param param2 - the second parameter */ void warn(String parameterizedMsg, Object param1, Object param2); /** * Log a message object with theWARN
level including the
* stack trace of the {@link Throwable}t
passed as parameter.
*
*
* @param msg the message object to log.
* @param t the exception to log, including its stack trace.
*/
void warn(Object msg, Throwable t);
/**
* Is the logger instance enabled for the ERROR level?
* @return true if debug is enabled.
*/
boolean isErrorEnabled();
/**
* Log a message object with the ERROR level.
* @param msg - the message object to be logged
*/
void error(Object msg);
/**
* Log a parameterized message object at the ERROR level.
*
* This form is useful in avoiding the superflous object creation * problem when invoking this method while it is disabled. *
* @param parameterizedMsg - the parameterized message object * @param param1 - the parameter */ void error(Object parameterizedMsg, Object param1); /** * Log a parameterized message object at the ERROR level. * *This form is useful in avoiding the superflous object creation * problem when invoking this method while it is disabled. *
* @param parameterizedMsg - the parameterized message object * @param param1 - the first parameter * @param param2 - the second parameter */ void error(String parameterizedMsg, Object param1, Object param2); /** * Log a message object with theERROR
level including the
* stack trace of the {@link Throwable}t
passed as parameter.
*
*
* @param msg the message object to log.
* @param t the exception to log, including its stack trace.
*/
void error(Object msg, Throwable t);
}
apache-log4j-extras1.2-1.2.17/src/main/java/org/apache/log4j/component/helpers/ 0000775 0000000 0000000 00000000000 12527427642 0026727 5 ustar 00root root 0000000 0000000 apache-log4j-extras1.2-1.2.17/src/main/java/org/apache/log4j/component/helpers/Constants.java 0000664 0000000 0000000 00000006616 12527427642 0031557 0 ustar 00root root 0000000 0000000 /*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.log4j.component.helpers;
/**
* Constants used internally throughout log4j.
*
*/
public interface Constants {
/**
* log4j package name string literal.
*/
String LOG4J_PACKAGE_NAME = "org.apache.log4j";
/**
* The name of the default repository is "default" (without the quotes).
*/
String DEFAULT_REPOSITORY_NAME = "default";
/**
* application string literal.
*/
String APPLICATION_KEY = "application";
/**
* hostname string literal.
*/
String HOSTNAME_KEY = "hostname";
/**
* receiver string literal.
*/
String RECEIVER_NAME_KEY = "receiver";
/**
* log4jid string literal.
*/
String LOG4J_ID_KEY = "log4jid";
/**
* time stamp pattern string literal.
*/
String TIMESTAMP_RULE_FORMAT = "yyyy/MM/dd HH:mm:ss";
/**
* The default property file name for automatic configuration.
*/
String DEFAULT_CONFIGURATION_FILE = "log4j.properties";
/**
* The default XML configuration file name for automatic configuration.
*/
String DEFAULT_XML_CONFIGURATION_FILE = "log4j.xml";
/**
* log4j.configuration string literal.
*/
String DEFAULT_CONFIGURATION_KEY = "log4j.configuration";
/**
* log4j.configuratorClass string literal.
*/
String CONFIGURATOR_CLASS_KEY = "log4j.configuratorClass";
/**
* JNDI context name string literal.
*/
String JNDI_CONTEXT_NAME = "java:comp/env/log4j/context-name";
/**
* TEMP_LIST_APPENDER string literal.
*/
String TEMP_LIST_APPENDER_NAME = "TEMP_LIST_APPENDER";
/**
* TEMP_CONSOLE_APPENDER string literal.
*/
String TEMP_CONSOLE_APPENDER_NAME = "TEMP_CONSOLE_APPENDER";
/**
* Codes URL string literal.
*/
String CODES_HREF =
"http://logging.apache.org/log4j/docs/codes.html";
/**
* ABSOLUTE string literal.
*/
String ABSOLUTE_FORMAT = "ABSOLUTE";
/**
* SimpleTimePattern for ABSOLUTE.
*/
String ABSOLUTE_TIME_PATTERN = "HH:mm:ss,SSS";
/**
* SimpleTimePattern for ABSOLUTE.
*/
String SIMPLE_TIME_PATTERN = "HH:mm:ss";
/**
* DATE string literal.
*/
String DATE_AND_TIME_FORMAT = "DATE";
/**
* SimpleTimePattern for DATE.
*/
String DATE_AND_TIME_PATTERN = "dd MMM yyyy HH:mm:ss,SSS";
/**
* ISO8601 string literal.
*/
String ISO8601_FORMAT = "ISO8601";
/**
* SimpleTimePattern for ISO8601.
*/
String ISO8601_PATTERN = "yyyy-MM-dd HH:mm:ss,SSS";
}
apache-log4j-extras1.2-1.2.17/src/main/java/org/apache/log4j/component/helpers/MessageFormatter.java0000664 0000000 0000000 00000013143 12527427642 0033044 0 ustar 00root root 0000000 0000000 /*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.log4j.component.helpers;
/**
* Formats messages according to very simple rules.
* See {@link #format(String,Object)} and
* {@link #format(String,Object,Object)} for more details.
*
* @author Ceki Gülcü
*/
public final class MessageFormatter {
/**
* Private formatter since all methods and members are static.
*/
private MessageFormatter() {
super();
}
/**
* Start of replacement block.
*/
private static final char DELIM_START = '{';
/**
* End of replacement block.
*/
private static final char DELIM_STOP = '}';
/**
* Performs single argument substitution for the 'messagePattern' passed as
* parameter.
*
* For example, MessageFormatter.format("Hi {}.", "there");
* will return the string "Hi there.".
*
* The {} pair is called the formatting element. It serves to designate the
* location where the argument needs to be inserted within the pattern.
*
* @param messagePattern
* The message pattern which will be parsed and formatted
* @param argument
* The argument to be inserted instead of the formatting element
* @return The formatted message
*/
public static String format(final String messagePattern,
final Object argument) {
int j = messagePattern.indexOf(DELIM_START);
int len = messagePattern.length();
char escape = 'x';
// if there are no { characters or { is the last character
// then we just return messagePattern
if (j == -1 || (j + 1 == len)) {
return messagePattern;
} else {
char delimStop = messagePattern.charAt(j + 1);
if (j > 0) {
escape = messagePattern.charAt(j - 1);
}
if ((delimStop != DELIM_STOP) || (escape == '\\')) {
// invalid DELIM_START/DELIM_STOP pair or espace character is
// present
return messagePattern;
} else {
StringBuffer sbuf = new StringBuffer(len + 20);
sbuf.append(messagePattern.substring(0, j));
sbuf.append(argument);
sbuf.append(messagePattern.substring(j + 2));
return sbuf.toString();
}
}
}
/**
* /**
* Performs a two argument substitution for the 'messagePattern' passed as
* parameter.
*
* For example, MessageFormatter.format("Hi {}. My name is {}.",
* "there", "David");
will return the string
* "Hi there. My name is David.".
*
* The '{}' pair is called a formatting element. It serves to designate the
* location where the arguments need to be inserted within
* the message pattern.
*
* @param messagePattern
* The message pattern which will be parsed and formatted
* @param arg1
* The first argument to replace the first formatting element
* @param arg2
* The second argument to replace the second formatting element
* @return The formatted message
*/
public static String format(final String messagePattern,
final Object arg1,
final Object arg2) {
int i = 0;
int len = messagePattern.length();
StringBuffer sbuf = new StringBuffer(messagePattern.length() + 50);
for (int l = 0; l < 2; l++) {
int j = messagePattern.indexOf(DELIM_START, i);
if (j == -1 || (j + 1 == len)) {
// no more variables
if (i == 0) { // this is a simple string
return messagePattern;
} else {
// add the tail string which contains no variables
// and return the result.
sbuf.append(messagePattern.substring(i,
messagePattern.length()));
return sbuf.toString();
}
} else {
char delimStop = messagePattern.charAt(j + 1);
if ((delimStop != DELIM_STOP)) {
// invalid DELIM_START/DELIM_STOP pair
sbuf.append(messagePattern.substring(i,
messagePattern.length()));
return sbuf.toString();
}
sbuf.append(messagePattern.substring(i, j));
if (l == 0) {
sbuf.append(arg1);
} else {
sbuf.append(arg2);
}
i = j + 2;
}
}
// append the characters following the second {} pair.
sbuf.append(messagePattern.substring(i, messagePattern.length()));
return sbuf.toString();
}
}
apache-log4j-extras1.2-1.2.17/src/main/java/org/apache/log4j/component/plugins/ 0000775 0000000 0000000 00000000000 12527427642 0026746 5 ustar 00root root 0000000 0000000 apache-log4j-extras1.2-1.2.17/src/main/java/org/apache/log4j/component/plugins/Pauseable.java 0000664 0000000 0000000 00000002253 12527427642 0031514 0 ustar 00root root 0000000 0000000 /*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.log4j.component.plugins;
/**
* Instances of this interface can be paused, and resumed.
*
* @author Paul Smith (psmith@apache.org)
*
*/
public interface Pauseable {
/**
* Set paused state.
* @param paused new value
*/
void setPaused(boolean paused);
/**
* Get paused state.
* @return paused state.
*/
boolean isPaused();
}
apache-log4j-extras1.2-1.2.17/src/main/java/org/apache/log4j/component/plugins/Plugin.java 0000664 0000000 0000000 00000011732 12527427642 0031053 0 ustar 00root root 0000000 0000000 /*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.log4j.component.plugins;
import org.apache.log4j.spi.LoggerRepository;
import org.apache.log4j.spi.OptionHandler;
import java.beans.PropertyChangeListener;
/**
* Defines the required interface for all Plugin objects.
*
* A plugin implements some specific functionality to extend * the log4j framework. Each plugin is associated with a specific * LoggerRepository, which it then uses/acts upon. The functionality * of the plugin is up to the developer. *
*Examples of plugins are Receiver and Watchdog. Receiver plugins * allow for remote logging events to be received and processed by * a repository as if the event was sent locally. Watchdog plugins * allow for a repository to be reconfigured when some "watched" * configuration data changes. * * @author Mark Womack (mwomack@apache.org) * @author Nicko Cadell * @author Paul Smith (psmith@apache.org) */ public interface Plugin extends OptionHandler { /** * Gets the name of the plugin. * * @return String the name of the plugin. */ String getName(); /** * Sets the name of the plugin. * * @param name the name of the plugin. */ void setName(String name); /** * Gets the logger repository for this plugin. * * @return the logger repository to which this plugin is attached. */ LoggerRepository getLoggerRepository(); /** * Sets the logger repository used by this plugin. This * repository will be used by the plugin functionality. * * @param repository the logger repository to attach this plugin to. */ void setLoggerRepository(LoggerRepository repository); /** * Adds a PropertyChangeListener to this instance which is * notified only by changes of the property with name propertyName. * * @param propertyName * the name of the property in standard JavaBean syntax * (e.g. for setName(), property="name") * @param l listener */ void addPropertyChangeListener( String propertyName, PropertyChangeListener l); /** * Adds a PropertyChangeListener that will be notified of all property * changes. * * @param l The listener to add. */ void addPropertyChangeListener(PropertyChangeListener l); /** * Removes a specific PropertyChangeListener from this instances * registry that has been mapped to be notified of all property * changes. * * @param l The listener to remove. */ void removePropertyChangeListener(PropertyChangeListener l); /** * Removes a specific PropertyChangeListener from this instance's * registry which has been previously registered to be notified * of only a specific property change. * * @param propertyName property name, may not be null. * @param l listener to be removed. */ void removePropertyChangeListener( String propertyName, PropertyChangeListener l); /** * True if the plugin is active and running. * * @return boolean true if the plugin is currently active. */ boolean isActive(); /** * Returns true if the testPlugin is considered to be "equivalent" to the * this plugin. The equivalency test is at the discretion of the plugin * implementation. The PluginRegistry will use this method when starting * new plugins to see if a given plugin is considered equivalent to an * already running plugin with the same name. If they are considered to * be equivalent, the currently running plugin will be left in place, and * the new plugin will not be started. *
* It is possible to override the equals() method, however this has * more meaning than is required for this simple test and would also * require the overriding of the hashCode() method as well. All of this * is more work than is needed, so this simple method is used instead. * * @param testPlugin The plugin to test equivalency against. * @return Returns true if testPlugin is considered to be equivelent. */ boolean isEquivalent(Plugin testPlugin); /** * Call when the plugin should be stopped. */ void shutdown(); } apache-log4j-extras1.2-1.2.17/src/main/java/org/apache/log4j/component/plugins/PluginEvent.java 0000664 0000000 0000000 00000002747 12527427642 0032063 0 ustar 00root root 0000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.log4j.component.plugins; import java.util.EventObject; /** * All Plugin events are encapsulated in this class, which * simply contains the source Plugin, but may in future include more * information. * * @author Paul Smith */ public class PluginEvent extends EventObject { /** * @param source The source plugin of the event */ PluginEvent(final Plugin source) { super(source); } /** * Returns the source Plugin of this event, which is simple * the getSource() method casted to Plugin for convenience. * * @return Plugin source of this event */ public Plugin getPlugin() { return (Plugin) getSource(); } } apache-log4j-extras1.2-1.2.17/src/main/java/org/apache/log4j/component/plugins/PluginListener.java 0000664 0000000 0000000 00000002470 12527427642 0032560 0 ustar 00root root 0000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* */ package org.apache.log4j.component.plugins; import java.util.EventListener; /** * PluginListeners are notified when plugins are started or stopped * by the PluginRegistry. * * @author Paul Smith (psmith@apache.org) */ public interface PluginListener extends EventListener { /** * Notification that plugin has started. * @param e event */ void pluginStarted(PluginEvent e); /** * Notification that plugin has stopped. * @param e event */ void pluginStopped(PluginEvent e); } apache-log4j-extras1.2-1.2.17/src/main/java/org/apache/log4j/component/plugins/PluginRegistry.java 0000664 0000000 0000000 00000021413 12527427642 0032601 0 ustar 00root root 0000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.log4j.component.plugins; import org.apache.log4j.component.spi.LoggerRepositoryEventListener; import org.apache.log4j.component.spi.LoggerRepositoryEx; import org.apache.log4j.spi.LoggerRepository; import java.util.*; /** * This is a registry for Plugin instances. It provides methods to * start and stop plugin objects individually and to stop all * plugins for a repository. * * @author Mark Womack * @author Paul Smith */ public final class PluginRegistry { /** * The pluginMap is keyed by plugin name and contains plugins as values. * key=plugin.getName, value=plugin */ private final Map pluginMap; /** * Logger repository. */ private final LoggerRepositoryEx loggerRepository; /** * the listener used to listen for repository events. */ private final RepositoryListener listener = new RepositoryListener(); /** * List of listeners. */ private final List listenerList = Collections.synchronizedList(new ArrayList()); /** * Creates a new instance. * @param repository logger repository. */ public PluginRegistry(final LoggerRepositoryEx repository) { super(); pluginMap = new HashMap(); this.loggerRepository = repository; this.loggerRepository.addLoggerRepositoryEventListener(listener); } /** * Get logger repository. * @return logger repository. */ public LoggerRepositoryEx getLoggerRepository() { return loggerRepository; } /** * Returns true if the specified name is already taken by * an existing Plugin registered within the scope of the specified * LoggerRepository. * * @param name The name to check the repository for * @return true if the name is already in use, otherwise false */ public boolean pluginNameExists(final String name) { synchronized (pluginMap) { return pluginMap.containsKey(name); } } /** * Adds a plugin to the plugin registry. * If a plugin with the same name exists * already, it is shutdown and removed. * * @param plugin the plugin to add. */ public void addPlugin(final Plugin plugin) { // put plugin into the repository's reciever map synchronized (pluginMap) { String name = plugin.getName(); // make sure the plugin has reference to repository plugin.setLoggerRepository(getLoggerRepository()); Plugin existingPlugin = (Plugin) pluginMap.get(name); if (existingPlugin != null) { existingPlugin.shutdown(); } // put the new plugin into the map pluginMap.put(name, plugin); firePluginStarted(plugin); } } /** * Calls the pluginStarted method on every registered PluginListener. * * @param plugin The plugin that has been started. */ private void firePluginStarted(final Plugin plugin) { PluginEvent e = null; synchronized (listenerList) { for (Iterator iter = listenerList.iterator(); iter.hasNext();) { PluginListener l = (PluginListener) iter.next(); if (e == null) { e = new PluginEvent(plugin); } l.pluginStarted(e); } } } /** * Calls the pluginStopped method for every registered PluginListner. * * @param plugin The plugin that has been stopped. */ private void firePluginStopped(final Plugin plugin) { PluginEvent e = null; synchronized (listenerList) { for (Iterator iter = listenerList.iterator(); iter.hasNext();) { PluginListener l = (PluginListener) iter.next(); if (e == null) { e = new PluginEvent(plugin); } l.pluginStopped(e); } } } /** * Returns all the plugins for a given repository. * * @return List list of plugins from the repository. */ public List getPlugins() { synchronized (pluginMap) { List pluginList = new ArrayList(pluginMap.size()); Iterator iter = pluginMap.values().iterator(); while (iter.hasNext()) { pluginList.add(iter.next()); } return pluginList; } } /** * Returns all the plugins for a given repository that are instances * of a certain class. * * @param pluginClass the class the plugin must implement to be selected. * @return List list of plugins from the repository. */ public List getPlugins(final Class pluginClass) { synchronized (pluginMap) { List pluginList = new ArrayList(pluginMap.size()); Iterator iter = pluginMap.values().iterator(); while (iter.hasNext()) { Object plugin = iter.next(); if (pluginClass.isInstance(plugin)) { pluginList.add(plugin); } } return pluginList; } } /** * Stops a plugin by plugin name and repository. * * @param pluginName the name of the plugin to stop. * @return Plugin the plugin, if stopped, or null if the * the plugin was not found in the registry. */ public Plugin stopPlugin(final String pluginName) { synchronized (pluginMap) { Plugin plugin = (Plugin) pluginMap.get(pluginName); if (plugin == null) { return null; } // shutdown the plugin plugin.shutdown(); // remove it from the plugin map pluginMap.remove(pluginName); firePluginStopped(plugin); // return it for future use return plugin; } } /** * Stops all plugins in the given logger repository. */ public void stopAllPlugins() { synchronized (pluginMap) { // remove the listener for this repository loggerRepository.removeLoggerRepositoryEventListener(listener); Iterator iter = pluginMap.values().iterator(); while (iter.hasNext()) { Plugin plugin = (Plugin) iter.next(); plugin.shutdown(); firePluginStopped(plugin); } } } /** * Adds a PluginListener to this registry to be notified * of PluginEvents. * * @param l PluginListener to add to this registry */ public void addPluginListener(final PluginListener l) { listenerList.add(l); } /** * Removes a particular PluginListener from this registry * such that it will no longer be notified of PluginEvents. * * @param l PluginListener to remove */ public void removePluginListener(final PluginListener l) { listenerList.remove(l); } /** * Internal class used to handle listener events from repositories. */ private class RepositoryListener implements LoggerRepositoryEventListener { /** * Stops all plugins associated with the repository being reset. * * @param repository the repository that was reset. */ public void configurationResetEvent(final LoggerRepository repository) { PluginRegistry.this.stopAllPlugins(); } /** * Called when the repository configuration is changed. * * @param repository the repository that was changed. */ public void configurationChangedEvent( final LoggerRepository repository) { // do nothing with this event } /** * Stops all plugins associated with the repository being shutdown. * * @param repository the repository being shutdown. */ public void shutdownEvent(final LoggerRepository repository) { PluginRegistry.this.stopAllPlugins(); } } } apache-log4j-extras1.2-1.2.17/src/main/java/org/apache/log4j/component/plugins/PluginSkeleton.java 0000664 0000000 0000000 00000015670 12527427642 0032565 0 ustar 00root root 0000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.log4j.component.plugins; import org.apache.log4j.component.spi.ComponentBase; import org.apache.log4j.spi.LoggerRepository; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import java.beans.PropertyChangeSupport; /** * A convienent abstract class for plugin subclasses that implements * the basic methods of the Plugin interface. Subclasses are required * to implement the isActive(), activateOptions(), and shutdown() * methods. * *Developers are not required to subclass PluginSkeleton to * develop their own plugins (they are only required to implement the * Plugin interface), but it provides a convenient base class to start * from. *
* Contributors: Nicko Cadell * * @author Mark Womack (mwomack@apache.org) * @author Paul Smith (psmith@apache.org) */ public abstract class PluginSkeleton extends ComponentBase implements Plugin { /** * Name of this plugin. */ protected String name = "plugin"; /** * Active state of plugin. */ protected boolean active; /** * This is a delegate that does all the PropertyChangeListener * support. */ private PropertyChangeSupport propertySupport = new PropertyChangeSupport(this); /** * Construct new instance. */ protected PluginSkeleton() { super(); } /** * Gets the name of the plugin. * * @return String the name of the plugin. */ public String getName() { return name; } /** * Sets the name of the plugin and notifies * PropertyChangeListeners of the change. * * @param newName the name of the plugin to set. */ public void setName(final String newName) { String oldName = this.name; this.name = newName; propertySupport.firePropertyChange("name", oldName, this.name); } /** * Gets the logger repository for this plugin. * * @return LoggerRepository the logger repository this plugin will affect. */ public LoggerRepository getLoggerRepository() { return repository; } /** * Sets the logger repository used by this plugin and notifies a * relevant PropertyChangeListeners registered. This * repository will be used by the plugin functionality. * * @param repository the logger repository that this plugin should affect. */ public void setLoggerRepository(final LoggerRepository repository) { Object oldValue = this.repository; this.repository = repository; firePropertyChange("loggerRepository", oldValue, this.repository); } /** * Returns whether this plugin is Active or not. * * @return true/false */ public synchronized boolean isActive() { return active; } /** * Returns true if the plugin has the same name and logger repository as the * testPlugin passed in. * * @param testPlugin The plugin to test equivalency against. * @return Returns true if testPlugin is considered to be equivalent. */ public boolean isEquivalent(final Plugin testPlugin) { return (repository == testPlugin.getLoggerRepository()) && ((this.name == null && testPlugin.getName() == null) || (this.name != null && name.equals(testPlugin.getName()))) && this.getClass().equals(testPlugin.getClass()); } /** * Add property change listener. * @param listener listener. */ public final void addPropertyChangeListener( final PropertyChangeListener listener) { propertySupport.addPropertyChangeListener(listener); } /** * Add property change listener for one property only. * @param propertyName property name. * @param listener listener. */ public final void addPropertyChangeListener( final String propertyName, final PropertyChangeListener listener) { propertySupport.addPropertyChangeListener(propertyName, listener); } /** * Remove property change listener. * @param listener listener. */ public final void removePropertyChangeListener( final PropertyChangeListener listener) { propertySupport.removePropertyChangeListener(listener); } /** * Remove property change listener on a specific property. * @param propertyName property name. * @param listener listener. */ public final void removePropertyChangeListener( final String propertyName, final PropertyChangeListener listener) { propertySupport.removePropertyChangeListener(propertyName, listener); } /** * Fire a property change event to appropriate listeners. * @param evt change event. */ protected final void firePropertyChange( final PropertyChangeEvent evt) { propertySupport.firePropertyChange(evt); } /** * Fire property change event to appropriate listeners. * @param propertyName property name. * @param oldValue old value. * @param newValue new value. */ protected final void firePropertyChange( final String propertyName, final boolean oldValue, final boolean newValue) { propertySupport.firePropertyChange(propertyName, oldValue, newValue); } /** * Fire property change event to appropriate listeners. * @param propertyName property name. * @param oldValue old value. * @param newValue new value. */ protected final void firePropertyChange( final String propertyName, final int oldValue, final int newValue) { propertySupport.firePropertyChange(propertyName, oldValue, newValue); } /** * Fire property change event to appropriate listeners. * @param propertyName property name. * @param oldValue old value. * @param newValue new value. */ protected final void firePropertyChange( final String propertyName, final Object oldValue, final Object newValue) { propertySupport.firePropertyChange(propertyName, oldValue, newValue); } } apache-log4j-extras1.2-1.2.17/src/main/java/org/apache/log4j/component/plugins/Receiver.java 0000664 0000000 0000000 00000011162 12527427642 0031356 0 ustar 00root root 0000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.log4j.component.plugins; import org.apache.log4j.Level; import org.apache.log4j.Logger; import org.apache.log4j.spi.LoggingEvent; import org.apache.log4j.component.spi.Thresholdable; /** * Defines the base class for Receiver plugins. * *Just as Appenders send logging events outside of the log4j * environment (to files, to smtp, to sockets, etc), Receivers bring * logging events inside the log4j environment. *
*Receivers are meant to support the receiving of * remote logging events from another process. For example, * SocketAppender "appends" a logging event to a socket, configured * for a specific host and port number. On the receiving side of * the socket can be a SocketReceiver object. The SocketReceiver * object receives the logging event, and then "posts" it to the * log4j environment (LoggerRepository) on the receiving machine, to * be handled by the configured appenders, etc. The various * settings in this environment (Logger levels, Appender filters & * thresholds) are applied to the received logging event. *
*Receivers can also be used to "import" log messages from other * logging packages into the log4j environment. *
*Receivers can be configured to post events to a given * LoggerRepository. *
*Subclasses of Receiver must implement the isActive(), * activateOptions(), and shutdown() methods. The doPost() method * is provided to standardize the "import" of remote events into * the repository. * * @author Mark Womack * @author Ceki Gülcü * @author Paul Smith (psmith@apache.org) */ public abstract class Receiver extends PluginSkeleton implements Thresholdable { /** * Threshold level. */ protected Level thresholdLevel; /** * Create new instance. */ protected Receiver() { super(); } /** * Sets the receiver theshold to the given level. * * @param level The threshold level events must equal or be greater * than before further processing can be done. */ public void setThreshold(final Level level) { Level oldValue = this.thresholdLevel; thresholdLevel = level; firePropertyChange("threshold", oldValue, this.thresholdLevel); } /** * Gets the current threshold setting of the receiver. * * @return Level The current threshold level of the receiver. */ public Level getThreshold() { return thresholdLevel; } /** * Returns true if the given level is equals or greater than the current * threshold value of the receiver. * * @param level The level to test against the receiver threshold. * @return boolean True if level is equal or greater than the * receiver threshold. */ public boolean isAsSevereAsThreshold(final Level level) { return ((thresholdLevel == null) || level.isGreaterOrEqual(thresholdLevel)); } /** * Posts the logging event to a logger in the configured logger * repository. * * @param event the log event to post to the local log4j environment. */ public void doPost(final LoggingEvent event) { // if event does not meet threshold, exit now if (!isAsSevereAsThreshold(event.getLevel())) { return; } // get the "local" logger for this event from the // configured repository. Logger localLogger = getLoggerRepository().getLogger(event.getLoggerName()); // if the logger level is greater or equal to the level // of the event, use the logger to append the event. if (event.getLevel() .isGreaterOrEqual(localLogger.getEffectiveLevel())) { // call the loggers appenders to process the event localLogger.callAppenders(event); } } } apache-log4j-extras1.2-1.2.17/src/main/java/org/apache/log4j/component/scheduler/ 0000775 0000000 0000000 00000000000 12527427642 0027243 5 ustar 00root root 0000000 0000000 apache-log4j-extras1.2-1.2.17/src/main/java/org/apache/log4j/component/scheduler/Job.java 0000664 0000000 0000000 00000002344 12527427642 0030623 0 ustar 00root root 0000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.log4j.component.scheduler; /** * Job is a very simple interface. It only has a single method {@link #execute} * which is called by the {@link Scheduler} when a task is ready for execution. *
* It is assumed that the execution context * are contained within the implementing * {@link Job} itself. * * @author Ceki Gülcü */ public interface Job { /** * Execute job. */ void execute(); } apache-log4j-extras1.2-1.2.17/src/main/java/org/apache/log4j/component/scheduler/Scheduler.java 0000664 0000000 0000000 00000021361 12527427642 0032027 0 ustar 00root root 0000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.log4j.component.scheduler; import java.util.List; import java.util.Vector; /** * A simple but still useful implementation of a Scheduler (in memory only). * * This implementation will work very well when the number of scheduled job is * small, say less than 100 jobs. If a larger number of events need to be * scheduled, than a better adapted data structure for the jobList can give * improved performance. * * @author Ceki */ public class Scheduler extends Thread { /** * Job list. */ List jobList; /** * If set true, scheduler has or should shut down. */ boolean shutdown = false; /** * Create new instance. */ public Scheduler() { super(); jobList = new Vector(); } /** * Find the index of a given job. * @param job job * @return -1 if the job could not be found. */ int findIndex(final Job job) { int size = jobList.size(); boolean found = false; int i = 0; for (; i < size; i++) { ScheduledJobEntry se = (ScheduledJobEntry) jobList.get(i); if (se.job == job) { found = true; break; } } if (found) { return i; } else { return -1; } } /** * Delete the given job. * @param job job. * @return true if the job could be deleted, and * false if the job could not be found or if the Scheduler is about to * shutdown in which case deletions are not permitted. */ public synchronized boolean delete(final Job job) { // if already shutdown in the process of shutdown, there is no // need to remove Jobs as they will never be executed. if (shutdown) { return false; } int i = findIndex(job); if (i != -1) { ScheduledJobEntry se = (ScheduledJobEntry) jobList.remove(i); if (se.job != job) { // this should never happen new IllegalStateException("Internal programming error"); } // if the job is the first on the list, // then notify the scheduler thread to schedule a new job if (i == 0) { this.notifyAll(); } return true; } else { return false; } } /** * Schedule a {@link Job} for execution at system time given by * thedesiredTime
parameter.
* @param job job to schedule.
* @param desiredTime desired time of execution.
*/
public synchronized void schedule(final Job job,
final long desiredTime) {
schedule(new ScheduledJobEntry(job, desiredTime));
}
/**
* Schedule a {@link Job} for execution at system time given by
* the desiredTime
parameter.
*
* The job will be rescheduled. It will execute with a frequency determined
* by the period parameter.
* @param job job to schedule.
* @param desiredTime desired time of execution.
* @param period repeat period.
*/
public synchronized void schedule(final Job job,
final long desiredTime,
final long period) {
schedule(new ScheduledJobEntry(job, desiredTime, period));
}
/**
* Change the period of a job. The original job must exist for its period
* to be changed.
*
* The method returns true if the period could be changed, and false
* otherwise.
* @param job job.
* @param newPeriod new repeat period.
* @return true if period could be changed.
*/
public synchronized boolean changePeriod(final Job job,
final long newPeriod) {
if (newPeriod <= 0) {
throw new IllegalArgumentException(
"Period must be an integer langer than zero");
}
int i = findIndex(job);
if (i == -1) {
return false;
} else {
ScheduledJobEntry se = (ScheduledJobEntry) jobList.get(i);
se.period = newPeriod;
return true;
}
}
/**
* Schedule a job.
* @param newSJE new job entry.
*/
private synchronized void schedule(final ScheduledJobEntry newSJE) {
// disallow new jobs after shutdown
if (shutdown) {
return;
}
int max = jobList.size();
long desiredExecutionTime = newSJE.desiredExecutionTime;
// find the index i such that timeInMillis < jobList[i]
int i = 0;
for (; i < max; i++) {
ScheduledJobEntry sje = (ScheduledJobEntry) jobList.get(i);
if (desiredExecutionTime < sje.desiredExecutionTime) {
break;
}
}
jobList.add(i, newSJE);
// if the jobList was empty, then notify the scheduler thread
if (i == 0) {
this.notifyAll();
}
}
/**
* Shut down scheduler.
*/
public synchronized void shutdown() {
shutdown = true;
}
/**
* Run scheduler.
*/
public synchronized void run() {
while (!shutdown) {
if (jobList.isEmpty()) {
linger();
} else {
ScheduledJobEntry sje = (ScheduledJobEntry) jobList.get(0);
long now = System.currentTimeMillis();
if (now >= sje.desiredExecutionTime) {
executeInABox(sje.job);
jobList.remove(0);
if (sje.period > 0) {
sje.desiredExecutionTime = now + sje.period;
schedule(sje);
}
} else {
linger(sje.desiredExecutionTime - now);
}
}
}
// clear out the job list to facilitate garbage collection
jobList.clear();
jobList = null;
System.out.println("Leaving scheduler run method");
}
/**
* We do not want a single failure to affect the whole scheduler.
* @param job job to execute.
*/
void executeInABox(final Job job) {
try {
job.execute();
} catch (Exception e) {
System.err.println("The execution of the job threw an exception");
e.printStackTrace(System.err);
}
}
/**
* Wait for notification.
*/
void linger() {
try {
while (jobList.isEmpty() && !shutdown) {
this.wait();
}
} catch (InterruptedException ie) {
shutdown = true;
}
}
/**
* Wait for notification or time to elapse.
* @param timeToLinger time to linger.
*/
void linger(final long timeToLinger) {
try {
this.wait(timeToLinger);
} catch (InterruptedException ie) {
shutdown = true;
}
}
/**
* Represents an entry in job scheduler.
*/
static final class ScheduledJobEntry {
/**
* Desired execution time.
*/
long desiredExecutionTime;
/**
* Job to run.
*/
Job job;
/**
* Repeat period.
*/
long period = 0;
/**
* Create new instance.
* @param job job
* @param desiredTime desired time.
*/
ScheduledJobEntry(final Job job, final long desiredTime) {
this(job, desiredTime, 0);
}
/**
* Create new instance.
* @param job job
* @param desiredTime desired time
* @param period repeat period
*/
ScheduledJobEntry(final Job job,
final long desiredTime,
final long period) {
super();
this.desiredExecutionTime = desiredTime;
this.job = job;
this.period = period;
}
}
}
apache-log4j-extras1.2-1.2.17/src/main/java/org/apache/log4j/component/spi/ 0000775 0000000 0000000 00000000000 12527427642 0026060 5 ustar 00root root 0000000 0000000 apache-log4j-extras1.2-1.2.17/src/main/java/org/apache/log4j/component/spi/Component.java 0000664 0000000 0000000 00000002501 12527427642 0030663 0 ustar 00root root 0000000 0000000 /*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.log4j.component.spi;
import org.apache.log4j.spi.LoggerRepository;
/**
* A common interface shared by log4j components.
*
* @author Ceki Gulcu
*/
public interface Component {
/**
* Set owning logger repository for this component. This operation can
* only be performed once.
* Once set, a subsequent attempt will throw an IllegalStateException.
*
* @param repository The repository where this appender is attached.
*/
void setLoggerRepository(LoggerRepository repository);
}
apache-log4j-extras1.2-1.2.17/src/main/java/org/apache/log4j/component/spi/ComponentBase.java 0000664 0000000 0000000 00000007237 12527427642 0031471 0 ustar 00root root 0000000 0000000 /*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.log4j.component.spi;
import org.apache.log4j.Logger;
import org.apache.log4j.component.ULogger;
import org.apache.log4j.spi.LoggerRepository;
/**
* Most log4j components derive from this class.
*
* @author Ceki Gulcu
*/
public class ComponentBase implements Component {
/**
* Error count limit.
*/
private static final int ERROR_COUNT_LIMIT = 3;
/**
* Logger repository.
*/
protected LoggerRepository repository;
/**
* Logger.
*/
private ULogger logger;
/**
* Error count.
*/
private int errorCount = 0;
/**
* Construct a new instance.
*/
protected ComponentBase() {
super();
}
/**
* Called by derived classes when they deem that the component has recovered
* from an erroneous state.
*/
protected void resetErrorCount() {
errorCount = 0;
}
/**
* Set the owning repository. The owning repository cannot be set more than
* once.
*
* @param repository repository
*/
public void setLoggerRepository(final LoggerRepository repository) {
if (this.repository == null) {
this.repository = repository;
} else if (this.repository != repository) {
throw new IllegalStateException("Repository has been already set");
}
}
/**
* Return the LoggerRepository to which this component is attached.
*
* @return Owning LoggerRepository
*/
protected LoggerRepository getLoggerRepository() {
return repository;
}
/**
* Return an instance specific logger to be used by the component itself.
* This logger is not intended to be accessed by the end-user, hence the
* protected keyword.
*
* In case the repository for this component is not set,
* this implementations returns a {@link SimpleULogger} instance.
*
* @return A ULogger instance.
*/
protected ULogger getLogger() {
if (logger == null) {
if (repository != null) {
Logger l = repository.getLogger(this.getClass().getName());
if (l instanceof ULogger) {
logger = (ULogger) l;
} else {
logger = new Log4JULogger(l);
}
} else {
logger = SimpleULogger.getLogger(this.getClass().getName());
}
}
return logger;
}
/**
* Frequently called methods in log4j components can invoke this method in
* order to avoid flooding the output when logging lasting error conditions.
*
* @return a regular logger, or a NOPLogger if called too frequently.
*/
protected ULogger getNonFloodingLogger() {
if (errorCount++ >= ERROR_COUNT_LIMIT) {
return NOPULogger.NOP_LOGGER;
} else {
return getLogger();
}
}
}
apache-log4j-extras1.2-1.2.17/src/main/java/org/apache/log4j/component/spi/ErrorItem.java 0000664 0000000 0000000 00000007401 12527427642 0030635 0 ustar 00root root 0000000 0000000 /*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.log4j.component.spi;
import java.io.PrintStream;
/**
* Used to store special log4j errors which cannot be logged using internal
* logging. Such errors include those occurring during the initial phases
* of log4j configuration or errors emanating from core components such as
* Logger or Hierarchy.
*
* @author Ceki Gulcu
*/
public class ErrorItem {
/**
* Message.
*/
String message;
/**
* Column.
*/
int colNumber = -1;
/**
* Line number.
*/
int lineNumber = -1;
/**
* Exception.
*/
Throwable exception;
/**
* Create new instance.
* @param message message
* @param e exception
*/
public ErrorItem(final String message, final Exception e) {
super();
this.message = message;
exception = e;
}
/**
* Creaet new instance.
* @param message message.
*/
public ErrorItem(final String message) {
this(message, null);
}
/**
* Get column number.
* @return column number.
*/
public int getColNumber() {
return colNumber;
}
/**
* Set column number.
* @param colNumber new column number.
*/
public void setColNumber(int colNumber) {
this.colNumber = colNumber;
}
/**
* Get exception.
* @return exception.
*/
public Throwable getException() {
return exception;
}
/**
* Set exception.
* @param exception exception
*/
public void setException(final Throwable exception) {
this.exception = exception;
}
/**
* Get line number.
* @return line number.
*/
public int getLineNumber() {
return lineNumber;
}
/**
* Set line number.
* @param lineNumber line number.
*/
public void setLineNumber(final int lineNumber) {
this.lineNumber = lineNumber;
}
/**
* Get message.
* @return message.
*/
public String getMessage() {
return message;
}
/**
* Set message.
* @param message message.
*/
public void setMessage(final String message) {
this.message = message;
}
/**
* String representation of ErrorItem.
* @return string.
*/
public String toString() {
String str =
"Reported error: \"" + message + "\"";
if (lineNumber != -1) {
str += " at line " + lineNumber + " column " + colNumber;
}
if (exception != null) {
str += (" with exception " + exception);
}
return str;
}
/**
* Dump the details of this ErrorItem to System.out.
*/
public void dump() {
dump(System.out);
}
/**
* Dump the details of this ErrorItem on the specified {@link PrintStream}.
* @param ps print stream.
*/
public void dump(final PrintStream ps) {
String str =
"Reported error: \"" + message + "\"";
if (lineNumber != -1) {
str += " at line " + lineNumber + " column " + colNumber;
}
ps.println(str);
if (exception != null) {
exception.printStackTrace(ps);
}
}
}
apache-log4j-extras1.2-1.2.17/src/main/java/org/apache/log4j/component/spi/Log4JULogger.java 0000664 0000000 0000000 00000012775 12527427642 0031143 0 ustar 00root root 0000000 0000000 /*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.log4j.component.spi;
import org.apache.log4j.Level;
import org.apache.log4j.Logger;
import org.apache.log4j.component.ULogger;
import org.apache.log4j.component.helpers.MessageFormatter;
/**
* An implementation of ULogger on org.apache.log4j.Logger.
*/
public final class Log4JULogger implements ULogger {
/**
* Wrapped log4j logger.
*/
private final Logger logger;
/**
* Create a new instance.
*
* @param l logger, may not be null.
*/
public Log4JULogger(final Logger l) {
super();
if (l == null) {
throw new NullPointerException("l");
}
logger = l;
}
/**
* {@inheritDoc}
*/
public boolean isDebugEnabled() {
return logger.isDebugEnabled();
}
/**
* {@inheritDoc}
*/
public void debug(final Object msg) {
logger.debug(msg);
}
/**
* {@inheritDoc}
*/
public void debug(final Object parameterizedMsg,
final Object param1) {
if (logger.isDebugEnabled()) {
logger.debug(MessageFormatter.format(
parameterizedMsg.toString(), param1));
}
}
/**
* {@inheritDoc}
*/
public void debug(final String parameterizedMsg,
final Object param1,
final Object param2) {
if (logger.isDebugEnabled()) {
logger.debug(MessageFormatter.format(
parameterizedMsg.toString(), param1, param2));
}
}
/**
* {@inheritDoc}
*/
public void debug(final Object msg,
final Throwable t) {
logger.debug(msg, t);
}
/**
* {@inheritDoc}
*/
public boolean isInfoEnabled() {
return logger.isInfoEnabled();
}
/**
* {@inheritDoc}
*/
public void info(final Object msg) {
logger.info(msg);
}
/**
* {@inheritDoc}
*/
public void info(final Object parameterizedMsg,
final Object param1) {
if (logger.isInfoEnabled()) {
logger.info(MessageFormatter.format(
parameterizedMsg.toString(), param1));
}
}
/**
* {@inheritDoc}
*/
public void info(final String parameterizedMsg,
final Object param1,
final Object param2) {
if (logger.isInfoEnabled()) {
logger.info(MessageFormatter.format(
parameterizedMsg.toString(),
param1,
param2));
}
}
/**
* {@inheritDoc}
*/
public void info(final Object msg, final Throwable t) {
logger.info(msg, t);
}
/**
* {@inheritDoc}
*/
public boolean isWarnEnabled() {
return logger.isEnabledFor(Level.WARN);
}
/**
* {@inheritDoc}
*/
public void warn(final Object msg) {
logger.warn(msg);
}
/**
* {@inheritDoc}
*/
public void warn(final Object parameterizedMsg,
final Object param1) {
if (logger.isEnabledFor(Level.WARN)) {
logger.warn(MessageFormatter.format(
parameterizedMsg.toString(), param1));
}
}
/**
* {@inheritDoc}
*/
public void warn(final String parameterizedMsg,
final Object param1,
final Object param2) {
if (logger.isEnabledFor(Level.WARN)) {
logger.warn(MessageFormatter.format(
parameterizedMsg.toString(), param1, param2));
}
}
/**
* {@inheritDoc}
*/
public void warn(final Object msg, final Throwable t) {
logger.warn(msg, t);
}
/**
* {@inheritDoc}
*/
public boolean isErrorEnabled() {
return logger.isEnabledFor(Level.ERROR);
}
/**
* {@inheritDoc}
*/
public void error(final Object msg) {
logger.error(msg);
}
/**
* {@inheritDoc}
*/
public void error(final Object parameterizedMsg, final Object param1) {
if (logger.isEnabledFor(Level.ERROR)) {
logger.error(MessageFormatter.format(
parameterizedMsg.toString(), param1));
}
}
/**
* {@inheritDoc}
*/
public void error(final String parameterizedMsg,
final Object param1,
final Object param2) {
if (logger.isEnabledFor(Level.ERROR)) {
logger.error(MessageFormatter.format(
parameterizedMsg.toString(), param1, param2));
}
}
/**
* {@inheritDoc}
*/
public void error(final Object msg, final Throwable t) {
logger.error(msg, t);
}
}
apache-log4j-extras1.2-1.2.17/src/main/java/org/apache/log4j/component/spi/LoggerEventListener.java 0000664 0000000 0000000 00000004111 12527427642 0032647 0 ustar 00root root 0000000 0000000 /*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.log4j.component.spi;
import org.apache.log4j.Appender;
import org.apache.log4j.Logger;
/**
Interface used to listen for Logger related events such as
add/remove appender or changing levels. Clients register an instance of
the interface and the instance is called back when the various events occur.
LoggerRepository provides methods for adding and removing
LoggerEventListener instances.
When implementing the methods of this interface, it is useful to remember
that the Logger can access the repository using its getRepository()
method.
@author Ceki Gülcü
@author Mark Womack
*/
public interface LoggerEventListener {
/**
Called when an appender is added to the logger.
@param logger The logger to which the appender was added.
@param appender The appender added to the logger. */
void appenderAddedEvent(Logger logger, Appender appender);
/**
Called when an appender is removed from the logger.
@param logger The logger from which the appender was removed.
@param appender The appender removed from the logger. */
void appenderRemovedEvent(Logger logger, Appender appender);
/**
Called when level changed on the logger.
@param logger The logger that changed levels. */
void levelChangedEvent(Logger logger);
}
LoggerRepositoryEventListener.java 0000664 0000000 0000000 00000003612 12527427642 0034675 0 ustar 00root root 0000000 0000000 apache-log4j-extras1.2-1.2.17/src/main/java/org/apache/log4j/component/spi /*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.log4j.component.spi;
import org.apache.log4j.spi.LoggerRepository;
/**
Interface used to listen for LoggerRepository related
events such as startup, reset, and shutdown. Clients register
an instance of the interface and the instance is called back
when the various events occur.
LoggerRepository provides methods for adding and removing
LoggerRepositoryEventListener instances.
@author Ceki Gülcü
@author Mark Womack
*/
public interface LoggerRepositoryEventListener {
/**
Called when the repository configuration is reset.
@param repository repository
*/
void configurationResetEvent(LoggerRepository repository);
/**
Called when the repository configuration is changed.
@param repository repository
*/
void configurationChangedEvent(LoggerRepository repository);
/**
Called when the repository is shutdown. When this method is
invoked, the repository is still valid (ie it has not been
shutdown, but will be after this method returns).
@param repository repository.
*/
void shutdownEvent(LoggerRepository repository);
}
apache-log4j-extras1.2-1.2.17/src/main/java/org/apache/log4j/component/spi/LoggerRepositoryEx.java 0000664 0000000 0000000 00000013216 12527427642 0032542 0 ustar 00root root 0000000 0000000 /*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.log4j.component.spi;
import org.apache.log4j.Appender;
import org.apache.log4j.Category;
import org.apache.log4j.Logger;
import org.apache.log4j.component.plugins.PluginRegistry;
import org.apache.log4j.component.scheduler.Scheduler;
import org.apache.log4j.spi.LoggerFactory;
import org.apache.log4j.spi.LoggerRepository;
import java.util.List;
import java.util.Map;
/**
A LoggerRepository
is used to create and retrieve
Loggers
. The relation between loggers in a repository
depends on the repository but typically loggers are arranged in a
named hierarchy.
In addition to the creational methods, a
LoggerRepository
can be queried for existing loggers,
can act as a point of registry for events related to loggers.
@author Ceki Gülcü
@author Mark Womack
@author Curt Arnold
*/
public interface LoggerRepositoryEx extends LoggerRepository {
/**
Add a {@link LoggerRepositoryEventListener} to the repository. The
listener will be called when repository events occur.
@param listener event listener, may not be null.
*/
void addLoggerRepositoryEventListener(
LoggerRepositoryEventListener listener);
/**
Remove a {@link LoggerRepositoryEventListener} from the repository.
@param listener listener.
*/
void removeLoggerRepositoryEventListener(
LoggerRepositoryEventListener listener);
/**
Add a {@link LoggerEventListener} to the repository. The listener
will be called when repository events occur.
@param listener listener, may not be null.
*/
void addLoggerEventListener(LoggerEventListener listener);
/**
Remove a {@link LoggerEventListener} from the repository.
@param listener listener, may not be null.
*/
void removeLoggerEventListener(LoggerEventListener listener);
/**
* Get the name of this logger repository.
* @return name, may not be null.
*/
String getName();
/**
* A logger repository is a named entity.
* @param repoName new name, may not be null.
*/
void setName(String repoName);
/**
* Is the current configuration of the repository in its original (pristine)
* state?
* @return true if repository is in original state.
*
*/
boolean isPristine();
/**
* Set the pristine flag.
* @param state state
* @see #isPristine
*/
void setPristine(boolean state);
/**
Requests that a appender removed event be sent to any registered
{@link LoggerEventListener}.
@param logger The logger from which the appender was removed.
@param appender The appender removed from the logger.
*/
void fireRemoveAppenderEvent(Category logger, Appender appender);
/**
Requests that a level changed event be sent to any registered
{@link LoggerEventListener}.
@param logger The logger which changed levels.
*/
void fireLevelChangedEvent(Logger logger);
/**
Requests that a configuration changed event be sent to any registered
{@link LoggerRepositoryEventListener}.
*/
void fireConfigurationChangedEvent();
/**
* Return the PluginRegisty for this LoggerRepository.
* @return plug in registry.
*/
PluginRegistry getPluginRegistry();
/**
* Return the {@link Scheduler} for this LoggerRepository.
* @return scheduler.
*/
Scheduler getScheduler();
/**
* Get the properties specific for this repository.
* @return property map.
*/
Map getProperties();
/**
* Get the property of this repository.
* @param key property key.
* @return key value or null if not set.
*/
String getProperty(String key);
/**
* Set a property of this repository.
* @param key key, may not be null.
* @param value new value, if null, property will be removed.
*/
void setProperty(String key, String value);
/**
* Errors which cannot be logged, go to the error list.
*
* @return List
*/
List getErrorList();
/**
* Errors which cannot be logged, go to the error list.
*
* @param errorItem an ErrorItem to add to the error list
*/
void addErrorItem(ErrorItem errorItem);
/**
* A LoggerRepository can also act as a store for various objects used
* by log4j components.
*
* @param key key, may not be null.
* @return The object stored under 'key'.
*/
Object getObject(String key);
/**
* Store an object under 'key'. If no object can be found, null is returned.
*
* @param key key, may not be null.
* @param value value, may be null.
*/
void putObject(String key, Object value);
/**
* Sets the logger factory used by LoggerRepository.getLogger(String).
* @param loggerFactory factory to use, may not be null
*/
void setLoggerFactory(LoggerFactory loggerFactory);
/**
* Returns the logger factory used by
* LoggerRepository.getLogger(String).
*
* @return non-null factory
*/
LoggerFactory getLoggerFactory();
}
apache-log4j-extras1.2-1.2.17/src/main/java/org/apache/log4j/component/spi/NOPULogger.java 0000664 0000000 0000000 00000010130 12527427642 0030637 0 ustar 00root root 0000000 0000000 /*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.log4j.component.spi;
import org.apache.log4j.component.ULogger;
/**
* A no operation (NOP) implementation of {@link ULogger}.
*
* @author Ceki Gülcü
*/
public final class NOPULogger implements ULogger {
/**
* The unique instance of NOPLogger.
*/
public static final NOPULogger NOP_LOGGER = new NOPULogger();
/**
* There is no point in people creating multiple instances of NullLogger.
* Hence, the private access modifier.
*/
private NOPULogger() {
super();
}
/**
* Get instance.
* @param name logger name.
* @return logger.
*/
public static NOPULogger getLogger(final String name) {
return NOP_LOGGER;
}
/**
* {@inheritDoc}
*/
public boolean isDebugEnabled() {
return false;
}
/**
* {@inheritDoc}
*/
public void debug(final Object msg) {
// NOP
}
/**
* {@inheritDoc}
*/
public void debug(final Object parameterizedMsg, final Object param1) {
// NOP
}
/**
* {@inheritDoc}
*/
public void debug(final String parameterizedMsg,
final Object param1,
final Object param2) {
// NOP
}
/**
* {@inheritDoc}
*/
public void debug(final Object msg, final Throwable t) {
// NOP
}
/**
* {@inheritDoc}
*/
public boolean isInfoEnabled() {
// NOP
return false;
}
/**
* {@inheritDoc}
*/
public void info(final Object msg) {
// NOP
}
/**
* {@inheritDoc}
*/
public void info(final Object parameterizedMsg, final Object param1) {
// NOP
}
/**
* {@inheritDoc}
*/
public void info(final String parameterizedMsg,
final Object param1, final Object param2) {
// NOP
}
/**
* {@inheritDoc}
*/
public void info(final Object msg, final Throwable t) {
// NOP
}
/**
* {@inheritDoc}
*/
public boolean isWarnEnabled() {
return false;
}
/**
* {@inheritDoc}
*/
public void warn(final Object msg) {
// NOP
}
/**
* {@inheritDoc}
*/
public void warn(final Object parameterizedMsg,
final Object param1) {
// NOP
}
/**
* {@inheritDoc}
*/
public void warn(final String parameterizedMsg,
final Object param1,
final Object param2) {
// NOP
}
/**
* {@inheritDoc}
*/
public void warn(final Object msg, final Throwable t) {
// NOP
}
/**
* {@inheritDoc}
*/
public boolean isErrorEnabled() {
return false;
}
/**
* {@inheritDoc}
*/
public void error(final Object msg) {
// NOP
}
/**
* {@inheritDoc}
*/
public void error(final Object parameterizedMsg, final Object param1) {
// NOP
}
/**
* {@inheritDoc}
*/
public void error(final String parameterizedMsg,
final Object param1,
final Object param2) {
// NOP
}
/**
* {@inheritDoc}
*/
public void error(final Object msg, final Throwable t) {
// NOP
}
}
apache-log4j-extras1.2-1.2.17/src/main/java/org/apache/log4j/component/spi/SimpleULogger.java 0000664 0000000 0000000 00000016776 12527427642 0031462 0 ustar 00root root 0000000 0000000 /*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.log4j.component.spi;
import org.apache.log4j.component.ULogger;
import org.apache.log4j.component.helpers.MessageFormatter;
/**
* A simple implementation that logs messages of level INFO or higher on
* the console (System.out
).
*
* The output includes the relative time in milliseconds, thread name, level, * logger name, and the message followed by the line separator for the host. * In log4j terms it amounts to the "%r [%t] %level %logger - %m%n" pattern. *
176 [main] INFO examples.Sort - Populating an array of 2 elements in reverse. 225 [main] INFO examples.SortAlgo - Entered the sort method. 304 [main] INFO SortAlgo.DUMP - Dump of interger array: 317 [main] INFO SortAlgo.DUMP - Element [0] = 0 331 [main] INFO SortAlgo.DUMP - Element [1] = 1 343 [main] INFO examples.Sort - The next log statement should be an error msg. 346 [main] ERROR SortAlgo.DUMP - Tried to dump an uninitialized array. at org.log4j.examples.SortAlgo.dump(SortAlgo.java:58) at org.log4j.examples.Sort.main(Sort.java:64) 467 [main] INFO examples.Sort - Exiting main method.* * @author Ceki Gülcü */ public final class SimpleULogger implements ULogger { /** * Logger name. */ private final String loggerName; /** * Mark the time when this class gets loaded into memory. */ private static long startTime = System.currentTimeMillis(); /** * Line separator. */ public static final String LINE_SEPARATOR = System.getProperty("line.separator"); /** * INFO string literal. */ private static final String INFO_STR = "INFO"; /** * WARN string literal. */ private static final String WARN_STR = "WARN"; /** * ERROR string literal. */ private static final String ERROR_STR = "ERROR"; /** * Constructor is private to force construction through getLogger. * @param name logger name */ private SimpleULogger(final String name) { super(); this.loggerName = name; } /** * Creates a new instance. * * @param name logger name * @return logger. */ public static SimpleULogger getLogger(final String name) { return new SimpleULogger(name); } /** * {@inheritDoc} */ public boolean isDebugEnabled() { return false; } /** * {@inheritDoc} */ public void debug(final Object msg) { // NOP } /** * {@inheritDoc} */ public void debug(final Object parameterizedMsg, final Object param1) { // NOP } /** * {@inheritDoc} */ public void debug(final String parameterizedMsg, final Object param1, final Object param2) { // NOP } /** * {@inheritDoc} */ public void debug(final Object msg, final Throwable t) { // NOP } /** * This is our internal implementation for logging regular (non-parameterized) * log messages. * * @param level level * @param message message * @param t throwable */ private void log(final String level, final String message, final Throwable t) { StringBuffer buf = new StringBuffer(); long millis = System.currentTimeMillis(); buf.append(millis - startTime); buf.append(" ["); buf.append(Thread.currentThread().getName()); buf.append("] "); buf.append(level); buf.append(" "); buf.append(loggerName); buf.append(" - "); buf.append(message); buf.append(LINE_SEPARATOR); System.out.print(buf.toString()); if (t != null) { t.printStackTrace(System.out); } System.out.flush(); } /** * For parameterized messages, first substitute parameters and then log. * * @param level level * @param parameterizedMsg message pattern * @param param1 param1 * @param param2 param2 */ private void parameterizedLog(final String level, final Object parameterizedMsg, final Object param1, final Object param2) { if (parameterizedMsg instanceof String) { String msgStr = (String) parameterizedMsg; msgStr = MessageFormatter.format(msgStr, param1, param2); log(level, msgStr, null); } else { // To be failsafe, we handle the case where 'messagePattern' is not // a String. Unless the user makes a mistake, this should not happen. log(level, parameterizedMsg.toString(), null); } } /** * {@inheritDoc} */ public boolean isInfoEnabled() { return true; } /** * {@inheritDoc} */ public void info(final Object msg) { log(INFO_STR, msg.toString(), null); } /** * {@inheritDoc} */ public void info(final Object parameterizedMsg, final Object param1) { parameterizedLog(INFO_STR, parameterizedMsg, param1, null); } /** * {@inheritDoc} */ public void info(final String parameterizedMsg, final Object param1, final Object param2) { parameterizedLog(INFO_STR, parameterizedMsg, param1, param2); } /** * {@inheritDoc} */ public void info(final Object msg, final Throwable t) { log(INFO_STR, msg.toString(), t); } /** * {@inheritDoc} */ public boolean isWarnEnabled() { return true; } /** * {@inheritDoc} */ public void warn(final Object msg) { log(WARN_STR, msg.toString(), null); } /** * {@inheritDoc} */ public void warn(final Object parameterizedMsg, final Object param1) { parameterizedLog(WARN_STR, parameterizedMsg, param1, null); } /** * {@inheritDoc} */ public void warn(final String parameterizedMsg, final Object param1, final Object param2) { parameterizedLog(WARN_STR, parameterizedMsg, param1, param2); } /** * {@inheritDoc} */ public void warn(final Object msg, final Throwable t) { log(WARN_STR, msg.toString(), t); } /** * {@inheritDoc} */ public boolean isErrorEnabled() { return true; } /** * {@inheritDoc} */ public void error(final Object msg) { log(ERROR_STR, msg.toString(), null); } /** * {@inheritDoc} */ public void error(final Object parameterizedMsg, final Object param1) { parameterizedLog(ERROR_STR, parameterizedMsg, param1, null); } /** * {@inheritDoc} */ public void error(final String parameterizedMsg, final Object param1, final Object param2) { parameterizedLog(ERROR_STR, parameterizedMsg, param1, param2); } /** * {@inheritDoc} */ public void error(final Object msg, final Throwable t) { log(ERROR_STR, msg.toString(), t); } } apache-log4j-extras1.2-1.2.17/src/main/java/org/apache/log4j/component/spi/Thresholdable.java 0000664 0000000 0000000 00000004223 12527427642 0031504 0 ustar 00root root 0000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.log4j.component.spi; import org.apache.log4j.Level; /** * An interface that defines the required methods for supporting the * setting and getting of a level threshold. Components should implement * this interface if logging events they process should meet a certain * threshold before being processed further. Examples of this are * Appenders and Receivers which will not process logging events unless * the event level is at or greater than a set threshold level. * * @author Paul Smith (psmith@apache.org) * @author Mark Womack */ public interface Thresholdable { /** * Sets the component theshold to the given level. * * @param level The threshold level events must equal or be greater * than before further processing can be done. */ void setThreshold(Level level); /** * Gets the current threshold setting of the component. * * @return Level The current threshold level of the component. */ Level getThreshold(); /** * Returns true if the given level is equals or greater than the current * threshold value of the component. * * @param level The level to test against the component threshold. * @return boolean True if level is equal or greater than the * component threshold. */ boolean isAsSevereAsThreshold(Level level); } apache-log4j-extras1.2-1.2.17/src/main/java/org/apache/log4j/extras/ 0000775 0000000 0000000 00000000000 12527427642 0024571 5 ustar 00root root 0000000 0000000 apache-log4j-extras1.2-1.2.17/src/main/java/org/apache/log4j/extras/DOMConfigurator.java 0000664 0000000 0000000 00000107217 12527427642 0030446 0 ustar 00root root 0000000 0000000 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.log4j.extras; import org.apache.log4j.Appender; import org.apache.log4j.Layout; import org.apache.log4j.Level; import org.apache.log4j.LogManager; import org.apache.log4j.Logger; import org.apache.log4j.config.PropertySetter; import org.apache.log4j.helpers.FileWatchdog; import org.apache.log4j.helpers.Loader; import org.apache.log4j.helpers.LogLog; import org.apache.log4j.helpers.OptionConverter; import org.apache.log4j.or.RendererMap; import org.apache.log4j.spi.AppenderAttachable; import org.apache.log4j.spi.Configurator; import org.apache.log4j.spi.ErrorHandler; import org.apache.log4j.spi.Filter; import org.apache.log4j.spi.LoggerFactory; import org.apache.log4j.spi.LoggerRepository; import org.apache.log4j.spi.OptionHandler; import org.apache.log4j.spi.RendererSupport; import org.apache.log4j.xml.SAXErrorHandler; import org.apache.log4j.xml.UnrecognizedElementHandler; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.NamedNodeMap; import org.w3c.dom.Node; import org.w3c.dom.NodeList; import org.xml.sax.EntityResolver; import org.xml.sax.InputSource; import org.xml.sax.SAXException; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.FactoryConfigurationError; import java.io.ByteArrayInputStream; import java.io.File; import java.io.IOException; import java.io.InputStream; import java.io.Reader; import java.lang.reflect.Method; import java.net.URL; import java.util.Hashtable; import java.util.Properties; /** * This is a duplicate (with minor modifications) * of the log4j 1.2.15 DOMConfigurator * renamed for use with earlier versions of log4j. * */ public class DOMConfigurator implements Configurator { static final String CONFIGURATION_TAG = "log4j:configuration"; static final String OLD_CONFIGURATION_TAG = "configuration"; static final String RENDERER_TAG = "renderer"; static final String APPENDER_TAG = "appender"; static final String APPENDER_REF_TAG = "appender-ref"; static final String PARAM_TAG = "param"; static final String LAYOUT_TAG = "layout"; static final String CATEGORY = "category"; static final String LOGGER = "logger"; static final String LOGGER_REF = "logger-ref"; static final String CATEGORY_FACTORY_TAG = "categoryFactory"; static final String LOGGER_FACTORY_TAG = "loggerFactory"; static final String NAME_ATTR = "name"; static final String CLASS_ATTR = "class"; static final String VALUE_ATTR = "value"; static final String ROOT_TAG = "root"; static final String ROOT_REF = "root-ref"; static final String LEVEL_TAG = "level"; static final String PRIORITY_TAG = "priority"; static final String FILTER_TAG = "filter"; static final String ERROR_HANDLER_TAG = "errorHandler"; static final String REF_ATTR = "ref"; static final String ADDITIVITY_ATTR = "additivity"; static final String THRESHOLD_ATTR = "threshold"; static final String CONFIG_DEBUG_ATTR = "configDebug"; static final String INTERNAL_DEBUG_ATTR = "debug"; private static final String RESET_ATTR = "reset"; static final String RENDERING_CLASS_ATTR = "renderingClass"; static final String RENDERED_CLASS_ATTR = "renderedClass"; static final String EMPTY_STR = ""; static final Class[] ONE_STRING_PARAM = new Class[] {String.class}; final static String dbfKey = "javax.xml.parsers.DocumentBuilderFactory"; // key: appenderName, value: appender private Hashtable appenderBag; private Properties props; private LoggerRepository repository; private LoggerFactory catFactory = null; /** No argument constructor. */ public DOMConfigurator() { appenderBag = new Hashtable(); } /** Used internally to parse appenders by IDREF name. */ protected Appender findAppenderByName(Document doc, String appenderName) { Appender appender = (Appender) appenderBag.get(appenderName); if(appender != null) { return appender; } else { // Doesn't work on DOM Level 1 : // Element element = doc.getElementById(appenderName); // Endre's hack: Element element = null; NodeList list = doc.getElementsByTagName("appender"); for (int t=0; t < list.getLength(); t++) { Node node = list.item(t); NamedNodeMap map= node.getAttributes(); Node attrNode = map.getNamedItem("name"); if (appenderName.equals(attrNode.getNodeValue())) { element = (Element) node; break; } } // Hack finished. if(element == null) { LogLog.error("No appender named ["+appenderName+"] could be found."); return null; } else { appender = parseAppender(element); if (appender != null) { appenderBag.put(appenderName, appender); } return appender; } } } /** Used internally to parse appenders by IDREF element. */ protected Appender findAppenderByReference(Element appenderRef) { String appenderName = subst(appenderRef.getAttribute(REF_ATTR)); Document doc = appenderRef.getOwnerDocument(); return findAppenderByName(doc, appenderName); } /** * Delegates unrecognized content to created instance if * it supports UnrecognizedElementParser. * @since 1.2.15 * @param instance instance, may be null. * @param element element, may not be null. * @param props properties * @throws IOException thrown if configuration of owner object * should be abandoned. */ private static void parseUnrecognizedElement(final Object instance, final Element element, final Properties props) throws Exception { boolean recognized = false; if (instance instanceof UnrecognizedElementHandler) { recognized = ((UnrecognizedElementHandler) instance).parseUnrecognizedElement( element, props); } if (!recognized) { LogLog.warn("Unrecognized element " + element.getNodeName()); } } /** * Delegates unrecognized content to created instance if * it supports UnrecognizedElementParser and catches and * logs any exception. * @since 1.2.15 * @param instance instance, may be null. * @param element element, may not be null. * @param props properties */ private static void quietParseUnrecognizedElement(final Object instance, final Element element, final Properties props) { try { parseUnrecognizedElement(instance, element, props); } catch (Exception ex) { LogLog.error("Error in extension content: ", ex); } } /** Used internally to parse an appender element. */ protected Appender parseAppender (Element appenderElement) { String className = subst(appenderElement.getAttribute(CLASS_ATTR)); LogLog.debug("Class name: [" + className+']'); try { Object instance = Loader.loadClass(className).newInstance(); Appender appender = (Appender)instance; PropertySetter propSetter = new PropertySetter(appender); appender.setName(subst(appenderElement.getAttribute(NAME_ATTR))); NodeList children = appenderElement.getChildNodes(); final int length = children.getLength(); for (int loop = 0; loop < length; loop++) { Node currentNode = children.item(loop); /* We're only interested in Elements */ if (currentNode.getNodeType() == Node.ELEMENT_NODE) { Element currentElement = (Element)currentNode; // Parse appender parameters if (currentElement.getTagName().equals(PARAM_TAG)) { setParameter(currentElement, propSetter); } // Set appender layout else if (currentElement.getTagName().equals(LAYOUT_TAG)) { appender.setLayout(parseLayout(currentElement)); } // Add filters else if (currentElement.getTagName().equals(FILTER_TAG)) { parseFilters(currentElement, appender); } else if (currentElement.getTagName().equals(ERROR_HANDLER_TAG)) { parseErrorHandler(currentElement, appender); } else if (currentElement.getTagName().equals(APPENDER_REF_TAG)) { String refName = subst(currentElement.getAttribute(REF_ATTR)); if(appender instanceof AppenderAttachable) { AppenderAttachable aa = (AppenderAttachable) appender; LogLog.debug("Attaching appender named ["+ refName+ "] to appender named ["+ appender.getName()+"]."); aa.addAppender(findAppenderByReference(currentElement)); } else { LogLog.error("Requesting attachment of appender named ["+ refName+ "] to appender named ["+ appender.getName()+ "] which does not implement org.apache.log4j.spi.AppenderAttachable."); } } else { parseUnrecognizedElement(instance, currentElement, props); } } } propSetter.activate(); return appender; } /* Yes, it's ugly. But all of these exceptions point to the same problem: we can't create an Appender */ catch (Exception oops) { LogLog.error("Could not create an Appender. Reported error follows.", oops); return null; } } /** Used internally to parse an {@link ErrorHandler} element. */ protected void parseErrorHandler(Element element, Appender appender) { ErrorHandler eh = (ErrorHandler) OptionConverter.instantiateByClassName( subst(element.getAttribute(CLASS_ATTR)), org.apache.log4j.spi.ErrorHandler.class, null); if(eh != null) { eh.setAppender(appender); PropertySetter propSetter = new PropertySetter(eh); NodeList children = element.getChildNodes(); final int length = children.getLength(); for (int loop = 0; loop < length; loop++) { Node currentNode = children.item(loop); if (currentNode.getNodeType() == Node.ELEMENT_NODE) { Element currentElement = (Element) currentNode; String tagName = currentElement.getTagName(); if(tagName.equals(PARAM_TAG)) { setParameter(currentElement, propSetter); } else if(tagName.equals(APPENDER_REF_TAG)) { eh.setBackupAppender(findAppenderByReference(currentElement)); } else if(tagName.equals(LOGGER_REF)) { String loggerName = currentElement.getAttribute(REF_ATTR); Logger logger = (catFactory == null) ? repository.getLogger(loggerName) : repository.getLogger(loggerName, catFactory); eh.setLogger(logger); } else if(tagName.equals(ROOT_REF)) { Logger root = repository.getRootLogger(); eh.setLogger(root); } else { quietParseUnrecognizedElement(eh, currentElement, props); } } } propSetter.activate(); appender.setErrorHandler(eh); } } /** Used internally to parse a filter element. */ protected void parseFilters(Element element, Appender appender) { String clazz = subst(element.getAttribute(CLASS_ATTR)); Filter filter = (Filter) OptionConverter.instantiateByClassName(clazz, Filter.class, null); if(filter != null) { PropertySetter propSetter = new PropertySetter(filter); NodeList children = element.getChildNodes(); final int length = children.getLength(); for (int loop = 0; loop < length; loop++) { Node currentNode = children.item(loop); if (currentNode.getNodeType() == Node.ELEMENT_NODE) { Element currentElement = (Element) currentNode; String tagName = currentElement.getTagName(); if(tagName.equals(PARAM_TAG)) { setParameter(currentElement, propSetter); } else { quietParseUnrecognizedElement(filter, currentElement, props); } } } propSetter.activate(); LogLog.debug("Adding filter of type ["+filter.getClass() +"] to appender named ["+appender.getName()+"]."); appender.addFilter(filter); } } /** Used internally to parse an category element. */ protected void parseCategory (Element loggerElement) { // Create a new org.apache.log4j.Category object from the
configuration
element as
defined in the log4j.dtd.
*/
static
public
void configure (Element element) {
DOMConfigurator configurator = new DOMConfigurator();
configurator.doConfigure(element, LogManager.getLoggerRepository());
}
/**
Like {@link #configureAndWatch(String, long)} except that the
default delay as defined by {@link FileWatchdog#DEFAULT_DELAY} is
used.
@param configFilename A log4j configuration file in XML format.
*/
static
public
void configureAndWatch(String configFilename) {
configureAndWatch(configFilename, FileWatchdog.DEFAULT_DELAY);
}
/**
Read the configuration file configFilename
if it
exists. Moreover, a thread will be created that will periodically
check if configFilename
has been created or
modified. The period is determined by the delay
argument. If a change or file creation is detected, then
configFilename
is read to configure log4j.
@param configFilename A log4j configuration file in XML format.
@param delay The delay in milliseconds to wait between each check.
*/
static
public
void configureAndWatch(String configFilename, long delay) {
XMLWatchdog xdog = new XMLWatchdog(configFilename);
xdog.setDelay(delay);
xdog.start();
}
private interface ParseAction {
Document parse(final DocumentBuilder parser) throws SAXException, IOException;
}
public
void doConfigure(final String filename, LoggerRepository repository) {
ParseAction action = new ParseAction() {
public Document parse(final DocumentBuilder parser) throws SAXException, IOException {
return parser.parse(new File(filename));
}
public String toString() {
return "file [" + filename + "]";
}
};
doConfigure(action, repository);
}
public
void doConfigure(final URL url, LoggerRepository repository) {
ParseAction action = new ParseAction() {
public Document parse(final DocumentBuilder parser) throws SAXException, IOException {
InputStream stream = url.openStream();
try {
InputSource src = new InputSource(stream);
src.setSystemId(url.toString());
return parser.parse(src);
} finally {
stream.close();
}
}
public String toString() {
return "url [" + url.toString() + "]";
}
};
doConfigure(action, repository);
}
/**
Configure log4j by reading in a log4j.dtd compliant XML
configuration file.
*/
public
void doConfigure(final InputStream inputStream, LoggerRepository repository)
throws FactoryConfigurationError {
ParseAction action = new ParseAction() {
public Document parse(final DocumentBuilder parser) throws SAXException, IOException {
InputSource inputSource = new InputSource(inputStream);
inputSource.setSystemId("dummy://log4j.dtd");
return parser.parse(inputSource);
}
public String toString() {
return "input stream [" + inputStream.toString() + "]";
}
};
doConfigure(action, repository);
}
/**
Configure log4j by reading in a log4j.dtd compliant XML
configuration file.
*/
public
void doConfigure(final Reader reader, LoggerRepository repository)
throws FactoryConfigurationError {
ParseAction action = new ParseAction() {
public Document parse(final DocumentBuilder parser) throws SAXException, IOException {
InputSource inputSource = new InputSource(reader);
inputSource.setSystemId("dummy://log4j.dtd");
return parser.parse(inputSource);
}
public String toString() {
return "reader [" + reader.toString() + "]";
}
};
doConfigure(action, repository);
}
/**
Configure log4j by reading in a log4j.dtd compliant XML
configuration file.
*/
protected
void doConfigure(final InputSource inputSource, LoggerRepository repository)
throws FactoryConfigurationError {
if (inputSource.getSystemId() == null) {
inputSource.setSystemId("dummy://log4j.dtd");
}
ParseAction action = new ParseAction() {
public Document parse(final DocumentBuilder parser) throws SAXException, IOException {
return parser.parse(inputSource);
}
public String toString() {
return "input source [" + inputSource.toString() + "]";
}
};
doConfigure(action, repository);
}
private final void doConfigure(final ParseAction action, final LoggerRepository repository)
throws FactoryConfigurationError {
DocumentBuilderFactory dbf = null;
this.repository = repository;
try {
LogLog.debug("System property is :"+
OptionConverter.getSystemProperty(dbfKey,
null));
dbf = DocumentBuilderFactory.newInstance();
LogLog.debug("Standard DocumentBuilderFactory search succeded.");
LogLog.debug("DocumentBuilderFactory is: "+dbf.getClass().getName());
} catch(FactoryConfigurationError fce) {
Exception e = fce.getException();
LogLog.debug("Could not instantiate a DocumentBuilderFactory.", e);
throw fce;
}
try {
dbf.setValidating(true);
DocumentBuilder docBuilder = dbf.newDocumentBuilder();
docBuilder.setErrorHandler(new SAXErrorHandler());
docBuilder.setEntityResolver(new Log4jEntityResolver());
Document doc = action.parse(docBuilder);
parse(doc.getDocumentElement());
} catch (Exception e) {
// I know this is miserable...
LogLog.error("Could not parse "+ action.toString() + ".", e);
}
}
/**
Configure by taking in an DOM element.
*/
public void doConfigure(Element element, LoggerRepository repository) {
this.repository = repository;
parse(element);
}
/**
A static version of {@link #doConfigure(String, LoggerRepository)}. */
static
public
void configure(String filename) throws FactoryConfigurationError {
new DOMConfigurator().doConfigure(filename,
LogManager.getLoggerRepository());
}
/**
A static version of {@link #doConfigure(URL, LoggerRepository)}.
*/
static
public
void configure(URL url) throws FactoryConfigurationError {
new DOMConfigurator().doConfigure(url, LogManager.getLoggerRepository());
}
/**
Used internally to configure the log4j framework by parsing a DOM
tree of XML elements based on log4j.dtd.
*/
protected
void parse(Element element) {
String rootElementName = element.getTagName();
if (!rootElementName.equals(CONFIGURATION_TAG)) {
if(rootElementName.equals(OLD_CONFIGURATION_TAG)) {
LogLog.warn("The <"+OLD_CONFIGURATION_TAG+
"> element has been deprecated.");
LogLog.warn("Use the <"+CONFIGURATION_TAG+"> element instead.");
} else {
LogLog.error("DOM element is - not a <"+CONFIGURATION_TAG+"> element.");
return;
}
}
String debugAttrib = subst(element.getAttribute(INTERNAL_DEBUG_ATTR));
LogLog.debug("debug attribute= \"" + debugAttrib +"\".");
// if the log4j.dtd is not specified in the XML file, then the
// "debug" attribute is returned as the empty string.
if(!debugAttrib.equals("") && !debugAttrib.equals("null")) {
LogLog.setInternalDebugging(OptionConverter.toBoolean(debugAttrib, true));
} else {
LogLog.debug("Ignoring " + INTERNAL_DEBUG_ATTR + " attribute.");
}
//
// reset repository before configuration if reset="true"
// on configuration element.
//
String resetAttrib = subst(element.getAttribute(RESET_ATTR));
LogLog.debug("reset attribute= \"" + resetAttrib +"\".");
if(!("".equals(resetAttrib)) &&
OptionConverter.toBoolean(resetAttrib, false)) {
repository.resetConfiguration();
}
String confDebug = subst(element.getAttribute(CONFIG_DEBUG_ATTR));
if(!confDebug.equals("") && !confDebug.equals("null")) {
LogLog.warn("The \""+CONFIG_DEBUG_ATTR+"\" attribute is deprecated.");
LogLog.warn("Use the \""+INTERNAL_DEBUG_ATTR+"\" attribute instead.");
LogLog.setInternalDebugging(OptionConverter.toBoolean(confDebug, true));
}
String thresholdStr = subst(element.getAttribute(THRESHOLD_ATTR));
LogLog.debug("Threshold =\"" + thresholdStr +"\".");
if(!"".equals(thresholdStr) && !"null".equals(thresholdStr)) {
repository.setThreshold(thresholdStr);
}
//Hashtable appenderBag = new Hashtable(11);
/* Building Appender objects, placing them in a local namespace
for future reference */
// First configure each category factory under the root element.
// Category factories need to be configured before any of
// categories they support.
//
String tagName = null;
Element currentElement = null;
Node currentNode = null;
NodeList children = element.getChildNodes();
final int length = children.getLength();
for (int loop = 0; loop < length; loop++) {
currentNode = children.item(loop);
if (currentNode.getNodeType() == Node.ELEMENT_NODE) {
currentElement = (Element) currentNode;
tagName = currentElement.getTagName();
if (tagName.equals(CATEGORY_FACTORY_TAG) || tagName.equals(LOGGER_FACTORY_TAG)) {
parseCategoryFactory(currentElement);
}
}
}
for (int loop = 0; loop < length; loop++) {
currentNode = children.item(loop);
if (currentNode.getNodeType() == Node.ELEMENT_NODE) {
currentElement = (Element) currentNode;
tagName = currentElement.getTagName();
if (tagName.equals(CATEGORY) || tagName.equals(LOGGER)) {
parseCategory(currentElement);
} else if (tagName.equals(ROOT_TAG)) {
parseRoot(currentElement);
} else if(tagName.equals(RENDERER_TAG)) {
parseRenderer(currentElement);
} else if (!(tagName.equals(APPENDER_TAG)
|| tagName.equals(CATEGORY_FACTORY_TAG)
|| tagName.equals(LOGGER_FACTORY_TAG))) {
quietParseUnrecognizedElement(repository, currentElement, props);
}
}
}
}
protected
String subst(final String value) {
return subst(value, props);
}
/**
* Substitutes property value for any references in expression.
*
* @param value value from configuration file, may contain
* literal text, property references or both
* @param props properties.
* @return evaluated expression, may still contain expressions
* if unable to expand.
* @since 1.2.15
*/
public static String subst(final String value, final Properties props) {
try {
return OptionConverter.substVars(value, props);
} catch (IllegalArgumentException e) {
LogLog.warn("Could not perform variable substitution.", e);
return value;
}
}
/**
* Sets a parameter based from configuration file content.
*
* @param elem param element, may not be null.
* @param propSetter property setter, may not be null.
* @param props properties
* @since 1.2.15
*/
public static void setParameter(final Element elem,
final PropertySetter propSetter,
final Properties props) {
String name = subst(elem.getAttribute("name"), props);
String value = (elem.getAttribute("value"));
value = subst(OptionConverter.convertSpecialChars(value), props);
propSetter.setProperty(name, value);
}
/**
* Creates an OptionHandler and processes any nested param elements
* but does not call activateOptions. If the class also supports
* UnrecognizedElementParser, the parseUnrecognizedElement method
* will be call for any child elements other than param.
*
* @param element element, may not be null.
* @param props properties
* @param expectedClass interface or class expected to be implemented
* by created class
* @return created class or null.
* @throws Exception thrown if the contain object should be abandoned.
* @since 1.2.15
*/
public static OptionHandler parseElement(final Element element,
final Properties props,
final Class expectedClass) throws Exception {
String clazz = subst(element.getAttribute("class"), props);
Object instance = OptionConverter.instantiateByClassName(clazz,
expectedClass, null);
if (instance instanceof OptionHandler) {
OptionHandler optionHandler = (OptionHandler) instance;
PropertySetter propSetter = new PropertySetter(optionHandler);
NodeList children = element.getChildNodes();
final int length = children.getLength();
for (int loop = 0; loop < length; loop++) {
Node currentNode = children.item(loop);
if (currentNode.getNodeType() == Node.ELEMENT_NODE) {
Element currentElement = (Element) currentNode;
String tagName = currentElement.getTagName();
if (tagName.equals("param")) {
setParameter(currentElement, propSetter, props);
} else {
parseUnrecognizedElement(instance, currentElement, props);
}
}
}
return optionHandler;
}
return null;
}
private static class XMLWatchdog extends FileWatchdog {
XMLWatchdog(String filename) {
super(filename);
}
/**
Call {@link DOMConfigurator#configure(String)} with the
filename
to reconfigure log4j. */
public
void doOnChange() {
new DOMConfigurator().doConfigure(filename,
LogManager.getLoggerRepository());
}
}
/**
* An {@link EntityResolver} specifically designed to return
* log4j.dtd
which is embedded within the log4j jar
* file.
*
* @author Paul Austin
* */
private static final class Log4jEntityResolver implements EntityResolver {
public InputSource resolveEntity (String publicId, String systemId) {
if (systemId.endsWith("log4j.dtd")) {
InputStream in = Log4jEntityResolver.class.getResourceAsStream("log4j.dtd");
if (in == null) {
LogLog.warn("Could not find [log4j.dtd] using [" +
Log4jEntityResolver.class.getClassLoader()
+ "] class loader, parsed without DTD.");
in = new ByteArrayInputStream(new byte[0]);
}
return new InputSource(in);
} else {
return null;
}
}
}
}
apache-log4j-extras1.2-1.2.17/src/main/java/org/apache/log4j/extras/SoundAppender.java 0000664 0000000 0000000 00000006011 12527427642 0030201 0 ustar 00root root 0000000 0000000 /*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.log4j.extras;
import java.applet.Applet;
import java.applet.AudioClip;
import java.net.MalformedURLException;
import java.net.URL;
import org.apache.log4j.AppenderSkeleton;
import org.apache.log4j.spi.LoggingEvent;
import org.apache.log4j.helpers.LogLog;
/**
* This class is equivalent to org.apache.log4j.varia.SoundAppender
* except for a package change to aid in use with OSGi.
*
* Plays a sound clip created using Applet.newAudioClip when an event is received.
*
* If the audio format is not supported, a message stating the SoundAppender could
* not be initialized is logged.
*
* Use a filter in combination with this appender to control when the appender is
* triggered.
*
* For example, in the appender definition, include a LevelMatchFilter configured
* to accept WARN or greater, followed by a DenyAllFilter.
*
* @author Scott Deboy
*
*/
public final class SoundAppender extends AppenderSkeleton {
private AudioClip clip;
private String audioURL;
public SoundAppender() {
}
/**
* Attempt to initialize the appender by creating a reference to an AudioClip.
*
* Will log a message if format is not supported, file not found, etc.
*
*/
public void activateOptions() {
/*
* AudioSystem.getAudioInputStream requires jdk 1.3,
* so we use applet.newaudioclip instead
*
*/
try {
clip = Applet.newAudioClip(new URL(audioURL));
} catch (MalformedURLException mue) {
LogLog.error("unable to initialize SoundAppender", mue);}
if (clip == null) {
LogLog.error("Unable to initialize SoundAppender");
}
}
/**
* Accessor
*
* @return audio file
*/
public String getAudioURL() {
return audioURL;
}
/**
* Mutator - common format for a file-based url:
* file:///c:/path/someaudioclip.wav
*
* @param audioURL
*/
public void setAudioURL(String audioURL) {
this.audioURL = audioURL;
}
/**
* Play the sound if an event is being processed
*/
protected void append(LoggingEvent event) {
if (clip != null) {
clip.play();
}
}
public void close() {
//nothing to do
}
/**
* Gets whether appender requires a layout.
* @return false
*/
public boolean requiresLayout() {
return false;
}
}
apache-log4j-extras1.2-1.2.17/src/main/java/org/apache/log4j/extras/UtilLoggingLevel.java 0000664 0000000 0000000 00000014417 12527427642 0030657 0 ustar 00root root 0000000 0000000 /*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.log4j.extras;
import java.util.ArrayList;
import java.util.List;
import org.apache.log4j.Level;
/**
* This class is identical to org.apache.log4j.helpers.UtilLoggingLevel
* except for a package change to aid in use with OSGi.
*
* An extension of the Level class that provides support for java.util.logging
* Levels.
*
* @author Scott Deboy (sdeboy@apache.org)
*/
public class UtilLoggingLevel extends Level {
/**
* Serialization version id.
*/
private static final long serialVersionUID = 909301162611820211L;
/**
* Numerical value for SEVERE.
*/
public static final int SEVERE_INT = 17000;
/**
* Numerical value for WARNING.
*/
public static final int WARNING_INT = 16000;
/**
* Numerical value for INFO.
*/
public static final int INFO_INT = 15000;
/**
* Numerical value for CONFIG.
*/
public static final int CONFIG_INT = 14000;
/**
* Numerical value for FINE.
*/
public static final int FINE_INT = 13000;
/**
* Numerical value for FINER.
*/
public static final int FINER_INT = 12000;
/**
* Numerical value for FINEST.
*/
public static final int FINEST_INT = 11000;
/**
* Numerical value for UNKNOWN.
*/
public static final int UNKNOWN_INT = 10000;
/**
* SEVERE.
*/
public static final UtilLoggingLevel SEVERE =
new UtilLoggingLevel(SEVERE_INT, "SEVERE", 0);
/**
* WARNING.
*/
public static final UtilLoggingLevel WARNING =
new UtilLoggingLevel(WARNING_INT, "WARNING", 4);
/**
* INFO.
*/
public static final UtilLoggingLevel INFO =
new UtilLoggingLevel(INFO_INT, "INFO", 5);
/**
* CONFIG.
*/
public static final UtilLoggingLevel CONFIG =
new UtilLoggingLevel(CONFIG_INT, "CONFIG", 6);
/**
* FINE.
*/
public static final UtilLoggingLevel FINE =
new UtilLoggingLevel(FINE_INT, "FINE", 7);
/**
* FINER.
*/
public static final UtilLoggingLevel FINER =
new UtilLoggingLevel(FINER_INT, "FINER", 8);
/**
* FINEST.
*/
public static final UtilLoggingLevel FINEST =
new UtilLoggingLevel(FINEST_INT, "FINEST", 9);
/**
* Create new instance.
* @param level numeric value for level.
* @param levelStr symbolic name for level.
* @param syslogEquivalent Equivalent syslog severity.
*/
protected UtilLoggingLevel(final int level,
final String levelStr,
final int syslogEquivalent) {
super(level, levelStr, syslogEquivalent);
}
/**
* Convert an integer passed as argument to a level. If the
* conversion fails, then this method returns the specified default.
* @param val numeric value.
* @param defaultLevel level to be returned if no level matches
* numeric value.
* @return matching level or default level.
*/
public static UtilLoggingLevel toLevel(final int val,
final UtilLoggingLevel defaultLevel) {
switch (val) {
case SEVERE_INT:
return SEVERE;
case WARNING_INT:
return WARNING;
case INFO_INT:
return INFO;
case CONFIG_INT:
return CONFIG;
case FINE_INT:
return FINE;
case FINER_INT:
return FINER;
case FINEST_INT:
return FINEST;
default:
return defaultLevel;
}
}
/**
* Gets level matching numeric value.
* @param val numeric value.
* @return matching level or UtilLoggerLevel.FINEST if no match.
*/
public static Level toLevel(final int val) {
return toLevel(val, FINEST);
}
/**
* Gets list of supported levels.
* @return list of supported levels.
*/
public static List getAllPossibleLevels() {
ArrayList list = new ArrayList();
list.add(FINE);
list.add(FINER);
list.add(FINEST);
list.add(INFO);
list.add(CONFIG);
list.add(WARNING);
list.add(SEVERE);
return list;
}
/**
* Get level with specified symbolic name.
* @param s symbolic name.
* @return matching level or Level.DEBUG if no match.
*/
public static Level toLevel(final String s) {
return toLevel(s, Level.DEBUG);
}
/**
* Get level with specified symbolic name.
* @param sArg symbolic name.
* @param defaultLevel level to return if no match.
* @return matching level or defaultLevel if no match.
*/
public static Level toLevel(final String sArg,
final Level defaultLevel) {
if (sArg == null) {
return defaultLevel;
}
String s = sArg.toUpperCase();
if (s.equals("SEVERE")) {
return SEVERE;
}
//if(s.equals("FINE")) return Level.FINE;
if (s.equals("WARNING")) {
return WARNING;
}
if (s.equals("INFO")) {
return INFO;
}
if (s.equals("CONFI")) {
return CONFIG;
}
if (s.equals("FINE")) {
return FINE;
}
if (s.equals("FINER")) {
return FINER;
}
if (s.equals("FINEST")) {
return FINEST;
}
return defaultLevel;
}
}
apache-log4j-extras1.2-1.2.17/src/main/java/org/apache/log4j/extras/XSLTLayout.java 0000664 0000000 0000000 00000043333 12527427642 0027432 0 ustar 00root root 0000000 0000000 /*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.log4j.extras;
import org.apache.log4j.Layout;
import org.apache.log4j.helpers.LogLog;
import org.apache.log4j.helpers.MDCKeySetExtractor;
import org.apache.log4j.spi.LoggingEvent;
import org.apache.log4j.spi.LocationInfo;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.Templates;
import javax.xml.transform.Transformer;
import javax.xml.transform.sax.TransformerHandler;
import javax.xml.transform.sax.SAXTransformerFactory;
import javax.xml.transform.stream.StreamSource;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.dom.DOMSource;
import javax.xml.parsers.DocumentBuilderFactory;
import java.io.InputStream;
import java.io.ByteArrayOutputStream;
import java.io.ByteArrayInputStream;
import java.util.Set;
import java.util.Properties;
import java.util.Arrays;
import java.util.TimeZone;
import java.nio.charset.Charset;
import java.nio.ByteBuffer;
import org.apache.log4j.pattern.CachedDateFormat;
import java.text.SimpleDateFormat;
import org.w3c.dom.Document;
import org.xml.sax.helpers.AttributesImpl;
/**
* This class is identical to org.apache.log4j.xml.XSLTLayout
* except for a change in package to aid in use with OSGi.
*
*
* XSLTLayout transforms each event as a document using
* a specified or default XSLT transform. The default
* XSLT transform produces a result similar to XMLLayout.
*
* When used with a FileAppender or similar, the transformation of
* an event will be appended to the results for previous
* transforms. If each transform results in an XML element, then
* resulting file will only be an XML entity
* since an XML document requires one and only one top-level element.
* To process the entity, reference it in a XML document like so:
*
* * <!DOCTYPE log4j:eventSet [<!ENTITY data SYSTEM "data.xml">]> * * <log4j:eventSet xmlns:log4j="http://jakarta.apache.org/log4j/"> * &data * </log4j:eventSet> * ** * The layout will detect the encoding and media-type specified in * the transform. If no encoding is specified in the transform, * an xsl:output element specifying the US-ASCII encoding will be inserted * before processing the transform. If an encoding is specified in the transform, * the same encoding should be explicitly specified for the appender. * * Extracting MDC values can be expensive when used with log4j releases * prior to 1.2.15. Output of MDC values is enabled by default * but be suppressed by setting properties to false. * * Extracting location info can be expensive regardless of log4j version. * Output of location info is disabled by default but can be enabled * by setting locationInfo to true. * * Embedded transforms in XML configuration should not * depend on namespace prefixes defined earlier in the document * as namespace aware parsing in not generally performed when * using DOMConfigurator. The transform will serialize * and reparse to get the namespace aware document needed. * */ public final class XSLTLayout extends Layout implements org.apache.log4j.xml.UnrecognizedElementHandler { /** * Namespace for XSLT. */ private static final String XSLT_NS = "http://www.w3.org/1999/XSL/Transform"; /** * Namespace for log4j events. */ private static final String LOG4J_NS = "http://jakarta.apache.org/log4j/"; /** * Whether location information should be written. */ private boolean locationInfo = false; /** * media-type (mime type) extracted from XSLT transform. */ private String mediaType = "text/plain"; /** * Encoding extracted from XSLT transform. */ private Charset encoding; /** * Transformer factory. */ private SAXTransformerFactory transformerFactory; /** * XSLT templates. */ private Templates templates; /** * Output stream. */ private final ByteArrayOutputStream outputStream; /** * Whether throwable information should be ignored. */ private boolean ignoresThrowable = false; /** * Whether properties should be extracted. */ private boolean properties = true; /** * Whether activateOptions has been called. */ private boolean activated = false; /** * DateFormat for UTC time. */ private final CachedDateFormat utcDateFormat; /** * Default constructor. * */ public XSLTLayout() { outputStream = new ByteArrayOutputStream(); transformerFactory = (SAXTransformerFactory) TransformerFactory.newInstance(); SimpleDateFormat zdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"); zdf.setTimeZone(TimeZone.getTimeZone("UTC")); utcDateFormat = new CachedDateFormat(zdf, 1000); } /** * {@inheritDoc} */ public synchronized String getContentType() { return mediaType; } /** * The LocationInfo option takes a boolean value. By default, it is * set to false which means there will be no location information output by * this layout. If the the option is set to true, then the file name and line * number of the statement at the origin of the log statement will be output. * *
* If you are embedding this layout within an {@link
* org.apache.log4j.net.SMTPAppender} then make sure to set the
* LocationInfo option of that appender as well.
*
* @param flag new value.
*/
public synchronized void setLocationInfo(final boolean flag) {
locationInfo = flag;
}
/**
* Gets whether location info should be output.
* @return if location is output.
*/
public synchronized boolean getLocationInfo() {
return locationInfo;
}
/**
* Sets whether MDC key-value pairs should be output, default false.
* @param flag new value.
*/
public synchronized void setProperties(final boolean flag) {
properties = flag;
}
/**
* Gets whether MDC key-value pairs should be output.
* @return true if MDC key-value pairs are output.
*/
public synchronized boolean getProperties() {
return properties;
}
/** {@inheritDoc} */
public synchronized void activateOptions() {
if (templates == null) {
try {
InputStream is = XSLTLayout.class.getResourceAsStream("default.xslt");
StreamSource ss = new StreamSource(is);
templates = transformerFactory.newTemplates(ss);
encoding = Charset.forName("US-ASCII");
mediaType = "text/plain";
} catch (Exception ex) {
LogLog.error("Error loading default.xslt", ex);
}
}
activated = true;
}
/**
* Gets whether throwables should not be output.
* @return true if throwables should not be output.
*/
public synchronized boolean ignoresThrowable() {
return ignoresThrowable;
}
/**
* Sets whether throwables should not be output.
* @param ignoresThrowable if true, throwables should not be output.
*/
public synchronized void setIgnoresThrowable(boolean ignoresThrowable) {
this.ignoresThrowable = ignoresThrowable;
}
/**
* {@inheritDoc}
*/
public synchronized String format(final LoggingEvent event) {
if (!activated) {
activateOptions();
}
if (templates != null && encoding != null) {
outputStream.reset();
try {
TransformerHandler transformer =
transformerFactory.newTransformerHandler(templates);
transformer.setResult(new StreamResult(outputStream));
transformer.startDocument();
//
// event element
//
AttributesImpl attrs = new AttributesImpl();
attrs.addAttribute(null, "logger", "logger",
"CDATA", event.getLoggerName());
attrs.addAttribute(null, "timestamp", "timestamp",
"CDATA", Long.toString(event.timeStamp));
attrs.addAttribute(null, "level", "level",
"CDATA", event.getLevel().toString());
attrs.addAttribute(null, "thread", "thread",
"CDATA", event.getThreadName());
StringBuffer buf = new StringBuffer();
utcDateFormat.format(event.timeStamp, buf);
attrs.addAttribute(null, "time", "time", "CDATA", buf.toString());
transformer.startElement(LOG4J_NS, "event", "event", attrs);
attrs.clear();
//
// message element
//
transformer.startElement(LOG4J_NS, "message", "message", attrs);
String msg = event.getRenderedMessage();
if (msg != null && msg.length() > 0) {
transformer.characters(msg.toCharArray(), 0, msg.length());
}
transformer.endElement(LOG4J_NS, "message", "message");
//
// NDC element
//
String ndc = event.getNDC();
if (ndc != null) {
transformer.startElement(LOG4J_NS, "NDC", "NDC", attrs);
char[] ndcChars = ndc.toCharArray();
transformer.characters(ndcChars, 0, ndcChars.length);
transformer.endElement(LOG4J_NS, "NDC", "NDC");
}
//
// throwable element unless suppressed
//
if (!ignoresThrowable) {
String[] s = event.getThrowableStrRep();
if (s != null) {
transformer.startElement(LOG4J_NS, "throwable",
"throwable", attrs);
char[] nl = new char[] { '\n' };
for (int i = 0; i < s.length; i++) {
char[] line = s[i].toCharArray();
transformer.characters(line, 0, line.length);
transformer.characters(nl, 0, nl.length);
}
transformer.endElement(LOG4J_NS, "throwable", "throwable");
}
}
//
// location info unless suppressed
//
//
if (locationInfo) {
LocationInfo locationInfo = event.getLocationInformation();
attrs.addAttribute(null, "class", "class", "CDATA",
locationInfo.getClassName());
attrs.addAttribute(null, "method", "method", "CDATA",
locationInfo.getMethodName());
attrs.addAttribute(null, "file", "file", "CDATA",
locationInfo.getFileName());
attrs.addAttribute(null, "line", "line", "CDATA",
locationInfo.getLineNumber());
transformer.startElement(LOG4J_NS, "locationInfo",
"locationInfo", attrs);
transformer.endElement(LOG4J_NS, "locationInfo",
"locationInfo");
}
if (properties) {
//
// write MDC contents out as properties element
//
Set mdcKeySet = MDCKeySetExtractor.INSTANCE.getPropertyKeySet(event);
if ((mdcKeySet != null) && (mdcKeySet.size() > 0)) {
attrs.clear();
transformer.startElement(LOG4J_NS,
"properties", "properties", attrs);
Object[] keys = mdcKeySet.toArray();
Arrays.sort(keys);
for (int i = 0; i < keys.length; i++) {
String key = keys[i].toString();
Object val = event.getMDC(key);
attrs.clear();
attrs.addAttribute(null, "name", "name", "CDATA", key);
attrs.addAttribute(null, "value", "value",
"CDATA", val.toString());
transformer.startElement(LOG4J_NS,
"data", "data", attrs);
transformer.endElement(LOG4J_NS, "data", "data");
}
}
}
transformer.endElement(LOG4J_NS, "event", "event");
transformer.endDocument();
String body = encoding.decode(
ByteBuffer.wrap(outputStream.toByteArray())).toString();
outputStream.reset();
//
// must remove XML declaration since it may
// result in erroneous encoding info
// if written by FileAppender in a different encoding
if (body.startsWith("");
if (endDecl != -1) {
for(endDecl += 2;
endDecl < body.length() &&
(body.charAt(endDecl) == '\n' || body.charAt(endDecl) == '\r');
endDecl++);
return body.substring(endDecl);
}
}
return body;
} catch (Exception ex) {
LogLog.error("Error during transformation", ex);
return ex.toString();
}
}
return "No valid transform or encoding specified.";
}
/**
* Sets XSLT transform.
* @param xsltdoc DOM document containing XSLT transform source,
* may be modified.
* @throws TransformerConfigurationException if transformer can not be
* created.
*/
public void setTransform(final Document xsltdoc)
throws TransformerConfigurationException {
//
// scan transform source for xsl:output elements
// and extract encoding, media (mime) type and output method
//
String encodingName = null;
mediaType = null;
String method = null;
NodeList nodes = xsltdoc.getElementsByTagNameNS(
XSLT_NS,
"output");
for(int i = 0; i < nodes.getLength(); i++) {
Element outputElement = (Element) nodes.item(i);
if (method == null || method.length() == 0) {
method = outputElement.getAttributeNS(null, "method");
}
if (encodingName == null || encodingName.length() == 0) {
encodingName = outputElement.getAttributeNS(null, "encoding");
}
if (mediaType == null || mediaType.length() == 0) {
mediaType = outputElement.getAttributeNS(null, "media-type");
}
}
if (mediaType == null || mediaType.length() == 0) {
if ("html".equals(method)) {
mediaType = "text/html";
} else if ("xml".equals(method)) {
mediaType = "text/xml";
} else {
mediaType = "text/plain";
}
}
//
// if encoding was not specified,
// add xsl:output encoding=US-ASCII to XSLT source
//
if (encodingName == null || encodingName.length() == 0) {
Element transformElement = xsltdoc.getDocumentElement();
Element outputElement = xsltdoc.
createElementNS(XSLT_NS, "output");
outputElement.setAttributeNS(null, "encoding", "US-ASCII");
transformElement.insertBefore(outputElement, transformElement.getFirstChild());
encoding = Charset.forName("US-ASCII");
} else {
encoding = Charset.forName(encodingName);
}
DOMSource transformSource = new DOMSource(xsltdoc);
templates = transformerFactory.newTemplates(transformSource);
}
/**
* {@inheritDoc}
*/
public boolean parseUnrecognizedElement(final Element element,
final Properties props)
throws Exception {
if (XSLT_NS.equals(element.getNamespaceURI()) ||
element.getNodeName().indexOf("transform") != -1 ||
element.getNodeName().indexOf("stylesheet") != -1) {
//
// DOMConfigurator typically not namespace aware
// serialize tree and reparse.
ByteArrayOutputStream os = new ByteArrayOutputStream();
DOMSource source = new DOMSource(element);
TransformerFactory transformerFactory = TransformerFactory.newInstance();
Transformer transformer = transformerFactory.newTransformer();
transformer.transform(source, new StreamResult(os));
ByteArrayInputStream is = new ByteArrayInputStream(os.toByteArray());
DocumentBuilderFactory domFactory = DocumentBuilderFactory.newInstance();
domFactory.setNamespaceAware(true);
Document xsltdoc = domFactory.newDocumentBuilder().parse(is);
setTransform(xsltdoc);
return true;
}
return false;
}
}
apache-log4j-extras1.2-1.2.17/src/main/java/org/apache/log4j/filter/ 0000775 0000000 0000000 00000000000 12527427642 0024550 5 ustar 00root root 0000000 0000000 apache-log4j-extras1.2-1.2.17/src/main/java/org/apache/log4j/filter/AndFilter.java 0000664 0000000 0000000 00000011256 12527427642 0027270 0 ustar 00root root 0000000 0000000 /*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.log4j.filter;
import org.apache.log4j.spi.Filter;
import org.apache.log4j.spi.LoggingEvent;
import org.apache.log4j.spi.OptionHandler;
import org.apache.log4j.xml.UnrecognizedElementHandler;
import org.w3c.dom.Element;
import java.util.Properties;
/**
* A filter that 'and's the results of any number of contained filters together.
*
* For the filter to process events, all contained filters must return Filter.ACCEPT.
*
* If the contained filters do not return Filter.ACCEPT, Filter.NEUTRAL is returned.
*
* If acceptOnMatch is set to true, Filter.ACCEPT is returned.
* If acceptOnMatch is set to false, Filter.DENY is returned.
*
* Here is an example config that will accept only events that contain BOTH
* a DEBUG level AND 'test' in the message:
*
*
You can add this filter to the end of a filter chain to
switch from the default "accept all unless instructed otherwise"
filtering behaviour to a "deny all unless instructed otherwise"
behaviour.
@author Ceki Gülcü
@since 0.9.0 */
public class DenyAllFilter extends Filter {
/**
Returns null
as there are no options.
@deprecated We now use JavaBeans introspection to configure
components. Options strings are no longer needed.
*/
public
String[] getOptionStrings() {
return null;
}
/**
No options to set.
@deprecated Use the setter method for the option directly instead
of the generic setOption
method.
*/
public
void setOption(String key, String value) {
}
/**
Always returns the integer constant {@link Filter#DENY}
regardless of the {@link LoggingEvent} parameter.
@param event The LoggingEvent to filter.
@return Always returns {@link Filter#DENY}.
*/
public
int decide(LoggingEvent event) {
return Filter.DENY;
}
}
apache-log4j-extras1.2-1.2.17/src/main/java/org/apache/log4j/filter/ExpressionFilter.java 0000664 0000000 0000000 00000011700 12527427642 0030717 0 ustar 00root root 0000000 0000000 /*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.log4j.filter;
import org.apache.log4j.rule.ExpressionRule;
import org.apache.log4j.rule.Rule;
import org.apache.log4j.spi.Filter;
import org.apache.log4j.spi.LoggingEvent;
/**
* A filter supporting complex expressions - supports both infix and postfix
* expressions (infix expressions must first be converted to postfix prior
* to processing).
*
See org.apache.log4j.chainsaw.LoggingEventFieldResolver.java
* for the correct names for logging event fields
* used when building expressions.
*
See org.apache.log4j.chainsaw.rule
package
* for a list of available
* rules which can be applied using the expression syntax.
*
See org.apache.log4j.chainsaw.RuleFactory
for the symbols
* used to activate the corresponding rules.
*
The filter admits two options LevelToMatch and
AcceptOnMatch. If there is an exact match between the value
of the LevelToMatch option and the level of the {@link
org.apache.log4j.spi.LoggingEvent}, then the {@link #decide} method returns {@link
org.apache.log4j.spi.Filter#ACCEPT} in case the AcceptOnMatch option value is set
to true
, if it is false
then {@link
org.apache.log4j.spi.Filter#DENY} is returned. If there is no match, {@link
org.apache.log4j.spi.Filter#NEUTRAL} is returned.
@author Ceki Gülcü
@since 1.2 */
public class LevelMatchFilter extends Filter {
/**
Do we return ACCEPT when a match occurs. Default is
true
. */
boolean acceptOnMatch = true;
/**
*/
Level levelToMatch;
public void setLevelToMatch(String level) {
levelToMatch = OptionConverter.toLevel(level, null);
}
public String getLevelToMatch() {
return (levelToMatch == null) ? null : levelToMatch.toString();
}
public void setAcceptOnMatch(boolean acceptOnMatch) {
this.acceptOnMatch = acceptOnMatch;
}
public boolean getAcceptOnMatch() {
return acceptOnMatch;
}
/**
Return the decision of this filter.
Returns {@link Filter#NEUTRAL} if the LevelToMatch option
is not set or if there is not match. Otherwise, if there is a
match, then the returned decision is {@link Filter#ACCEPT} if the
AcceptOnMatch property is set to true
. The
returned decision is {@link Filter#DENY} if the
AcceptOnMatch property is set to false.
*/
public int decide(LoggingEvent event) {
if (this.levelToMatch == null) {
return Filter.NEUTRAL;
}
boolean matchOccured = false;
if (this.levelToMatch.equals(event.getLevel())) {
matchOccured = true;
}
if (matchOccured) {
if (this.acceptOnMatch) {
return Filter.ACCEPT;
} else {
return Filter.DENY;
}
} else {
return Filter.NEUTRAL;
}
}
}
apache-log4j-extras1.2-1.2.17/src/main/java/org/apache/log4j/filter/LevelRangeFilter.java 0000664 0000000 0000000 00000010305 12527427642 0030604 0 ustar 00root root 0000000 0000000 /*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.log4j.filter;
import org.apache.log4j.Level;
import org.apache.log4j.spi.Filter;
import org.apache.log4j.spi.LoggingEvent;
/**
This is a very simple filter based on level matching, which can be
used to reject messages with priorities outside a certain range.
The filter admits three options LevelMin, LevelMax and AcceptOnMatch.
If the level of the {@link org.apache.log4j.spi.LoggingEvent} is not between Min and Max (inclusive), then {@link org.apache.log4j.spi.Filter#DENY} is returned.
If the Logging event level is within the specified range, then if AcceptOnMatch is true, {@link org.apache.log4j.spi.Filter#ACCEPT} is returned, and if AcceptOnMatch is false, {@link org.apache.log4j.spi.Filter#NEUTRAL} is returned.
If LevelMin
is not defined, then there is no
minimum acceptable level (ie a level is never rejected for
being too "low"/unimportant). If LevelMax
is not
defined, then there is no maximum acceptable level (ie a
level is never rejected for beeing too "high"/important).
Refer to the {@link
org.apache.log4j.AppenderSkeleton#setThreshold setThreshold} method
available to all
appenders extending {@link
org.apache.log4j.AppenderSkeleton} for a more convenient way to
filter out events by level.
@author Simon Kitching
@author based on code by Ceki Gülcü
*/
public class LevelRangeFilter extends Filter {
/**
Do we return ACCEPT when a match occurs. Default is
false
, so that later filters get run by default */
boolean acceptOnMatch = false;
Level levelMin;
Level levelMax;
/**
Return the decision of this filter.
*/
public
int decide(LoggingEvent event) {
if(this.levelMin != null
&& event.getLevel().isGreaterOrEqual(levelMin) == false) {
// level of event is less than minimum
return Filter.DENY;
}
if(this.levelMax != null
&& event.getLevel().toInt() > levelMax.toInt()) {
// level of event is greater than maximum
// Alas, there is no Level.isGreater method. and using
// a combo of isGreaterOrEqual && !Equal seems worse than
// checking the int values of the level objects..
return Filter.DENY;
}
if (acceptOnMatch) {
// this filter set up to bypass later filters and always return
// accept if level in range
return Filter.ACCEPT;
}
else {
// event is ok for this filter; allow later filters to have a look..
return Filter.NEUTRAL;
}
}
/**
Get the value of the LevelMax
option. */
public
Level getLevelMax() {
return levelMax;
}
/**
Get the value of the LevelMin
option. */
public
Level getLevelMin() {
return levelMin;
}
/**
Get the value of the AcceptOnMatch
option.
*/
public
boolean getAcceptOnMatch() {
return acceptOnMatch;
}
/**
Set the LevelMax
option.
*/
public
void setLevelMax(Level levelMax) {
this.levelMax = levelMax;
}
/**
Set the LevelMin
option.
*/
public
void setLevelMin(Level levelMin) {
this.levelMin = levelMin;
}
/**
Set the AcceptOnMatch
option.
*/
public
void setAcceptOnMatch(boolean acceptOnMatch) {
this.acceptOnMatch = acceptOnMatch;
}
}
apache-log4j-extras1.2-1.2.17/src/main/java/org/apache/log4j/filter/LocationInfoFilter.java 0000664 0000000 0000000 00000006162 12527427642 0031152 0 ustar 00root root 0000000 0000000 /*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.log4j.filter;
import org.apache.log4j.rule.ExpressionRule;
import org.apache.log4j.rule.Rule;
import org.apache.log4j.spi.Filter;
import org.apache.log4j.spi.LoggingEvent;
/**
* Location information is usually specified at the appender level -
* all events associated
* with an appender either create and parse stack traces or they do not.
* This is an expensive operation and in some cases not needed
* for all events associated with an appender.
*
* This filter creates event-level location information only
* if the provided expression evaluates to true.
*
* For information on expression syntax,
* see org.apache.log4j.rule.ExpressionRule
*
* @author Scott Deboy sdeboy@apache.org
*/
public class LocationInfoFilter extends Filter {
/**
* Convert to in-fix to post-fix.
*/
boolean convertInFixToPostFix = true;
/**
* Expression.
*/
String expression;
/**
* Compiled expression.
*/
Rule expressionRule;
/**
* {@inheritDoc}
*/
public void activateOptions() {
expressionRule =
ExpressionRule.getRule(expression, !convertInFixToPostFix);
}
/**
* Set expression.
* @param exp expression.
*/
public void setExpression(final String exp) {
this.expression = exp;
}
/**
* Get expression.
* @return expression.
*/
public String getExpression() {
return expression;
}
/**
* Set whether in-fix expressions should be converted to post-fix.
* @param newValue if true, convert/
*/
public void setConvertInFixToPostFix(final boolean newValue) {
this.convertInFixToPostFix = newValue;
}
/**
* Set whether in-fix expressions should be converted to post-fix.
* @return if true, expressions are converted.
*/
public boolean getConvertInFixToPostFix() {
return convertInFixToPostFix;
}
/**
* If this event does not already contain location information,
* evaluate the event against the expression.
*
* If the expression evaluates to true,
* force generation of location information by
* calling getLocationInfo.
*
* @param event event
* @return Filter.NEUTRAL.
*/
public int decide(final LoggingEvent event) {
if (expressionRule.evaluate(event, null)) {
event.getLocationInformation();
}
return Filter.NEUTRAL;
}
}
apache-log4j-extras1.2-1.2.17/src/main/java/org/apache/log4j/filter/LoggerMatchFilter.java 0000664 0000000 0000000 00000006117 12527427642 0030762 0 ustar 00root root 0000000 0000000 /*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.log4j.filter;
import org.apache.log4j.spi.Filter;
import org.apache.log4j.spi.LoggingEvent;
/**
This is a very simple filter based on logger name matching.
The filter admits two options LoggerToMatch and
AcceptOnMatch. If there is an exact match between the value
of the LoggerToMatch option and the logger of the {@link
org.apache.log4j.spi.LoggingEvent}, then the {@link #decide} method returns {@link
org.apache.log4j.spi.Filter#ACCEPT} in case the AcceptOnMatch option value is set
to true
, if it is false
then {@link
org.apache.log4j.spi.Filter#DENY} is returned. If there is no match, {@link
org.apache.log4j.spi.Filter#NEUTRAL} is returned. A loggerToMatch of "root"
matches both the root logger and a logger named "root".
*/
public class LoggerMatchFilter extends Filter {
/**
Do we return ACCEPT when a match occurs. Default is
true
. */
private boolean acceptOnMatch = true;
/**
* Logger name, may be null or empty in which case it matches root.
*/
private String loggerToMatch = "root";
/**
* Sets logger name.
* @param logger logger name.
*/
public void setLoggerToMatch(final String logger) {
if (logger == null) {
loggerToMatch = "root";
} else {
loggerToMatch = logger;
}
}
/**
* Gets logger name.
* @return logger name.
*/
public String getLoggerToMatch() {
return loggerToMatch;
}
/**
* Sets whether a match should result in acceptance.
* @param acceptOnMatch if true, accept if logger name matches, otherwise reject.
*/
public void setAcceptOnMatch(final boolean acceptOnMatch) {
this.acceptOnMatch = acceptOnMatch;
}
/**
* Gets whether a match should result in acceptance.
* @return true if event is accepted if logger name matches.
*/
public boolean getAcceptOnMatch() {
return acceptOnMatch;
}
/**
* {@inheritDoc}
*/
public int decide(final LoggingEvent event) {
boolean matchOccured = loggerToMatch.equals(event.getLoggerName());
if (matchOccured) {
if (this.acceptOnMatch) {
return Filter.ACCEPT;
} else {
return Filter.DENY;
}
} else {
return Filter.NEUTRAL;
}
}
}
apache-log4j-extras1.2-1.2.17/src/main/java/org/apache/log4j/filter/StringMatchFilter.java 0000664 0000000 0000000 00000004616 12527427642 0031013 0 ustar 00root root 0000000 0000000 /*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.log4j.filter;
import org.apache.log4j.spi.Filter;
import org.apache.log4j.spi.LoggingEvent;
/**
This is a very simple filter based on string matching.
The filter admits two options StringToMatch and
AcceptOnMatch. If there is a match between the value of the
StringToMatch option and the message of the {@link LoggingEvent},
then the {@link #decide(LoggingEvent)} method returns
{@link org.apache.log4j.spi.Filter#ACCEPT} if
the AcceptOnMatch option value is true, if it is false then
{@link org.apache.log4j.spi.Filter#DENY} is returned. If there is no match, {@link
org.apache.log4j.spi.Filter#NEUTRAL} is returned.
@author Ceki Gülcü
@since 0.9.0
*/
public class StringMatchFilter extends Filter {
boolean acceptOnMatch = true;
String stringToMatch;
public
void setStringToMatch(String s) {
stringToMatch = s;
}
public
String getStringToMatch() {
return stringToMatch;
}
public
void setAcceptOnMatch(boolean acceptOnMatch) {
this.acceptOnMatch = acceptOnMatch;
}
public
boolean getAcceptOnMatch() {
return acceptOnMatch;
}
/**
Returns {@link Filter#NEUTRAL} is there is no string match.
*/
public
int decide(LoggingEvent event) {
String msg = event.getRenderedMessage();
if(msg == null || stringToMatch == null)
return Filter.NEUTRAL;
if( msg.indexOf(stringToMatch) == -1 ) {
return Filter.NEUTRAL;
} else { // we've got a match
if(acceptOnMatch) {
return Filter.ACCEPT;
} else {
return Filter.DENY;
}
}
}
}
apache-log4j-extras1.2-1.2.17/src/main/java/org/apache/log4j/filter/TimeFilter.java 0000664 0000000 0000000 00000010411 12527427642 0027454 0 ustar 00root root 0000000 0000000 /*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.log4j.filter;
import org.apache.log4j.helpers.LogLog;
import org.apache.log4j.spi.Filter;
import org.apache.log4j.spi.LoggingEvent;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.TimeZone;
/**
* Filters events that fall within a specified time period
* in each day.
*
*/
public final class TimeFilter extends Filter {
private boolean acceptOnMatch;
/**
* Starting offset from midnight in milliseconds.
*/
private long start;
/**
* Ending offset from midnight in milliseconds.
*/
private long end;
/**
* Timezone.
*/
private Calendar calendar;
/**
* Length of hour in milliseconds.
*/
private static final long HOUR_MS = 3600000;
/**
* Length of minute in milliseconds.
*/
private static final long MINUTE_MS = 60000;
/**
* Length of second in milliseconds.
*/
private static final long SECOND_MS = 1000;
/**
* Constructor.
*/
public TimeFilter() {
acceptOnMatch = true;
start = 0;
end = Long.MAX_VALUE;
calendar = Calendar.getInstance();
}
/**
* Set start (inclusive) of time span.
* @param s string representation of start time as HH:mm:ss.
*/
public void setStart(final String s) {
SimpleDateFormat stf = new SimpleDateFormat("HH:mm:ss");
stf.setTimeZone(TimeZone.getTimeZone("UTC"));
try {
start = stf.parse(s).getTime();
} catch(ParseException ex) {
LogLog.warn("Error parsing start value " + s, ex);
}
}
/**
* Set end (exclusive) of time span.
* @param s string representation of end time as HH:mm:ss.
*/
public void setEnd(final String s) {
SimpleDateFormat stf = new SimpleDateFormat("HH:mm:ss");
stf.setTimeZone(TimeZone.getTimeZone("UTC"));
try {
end = stf.parse(s).getTime();
} catch(ParseException ex) {
LogLog.warn("Error parsing end value " + s, ex);
}
}
/**
* Set timezone.
* @param s time zone.
*/
public void setTimeZone(final String s) {
if (s == null) {
calendar = Calendar.getInstance();
} else {
calendar = Calendar.getInstance(TimeZone.getTimeZone(s));
}
}
/**
* Sets whether an event within the timespan should be accepted or denied.
* @param acceptOnMatch true if matching event should be accepted.
*/
public synchronized void setAcceptOnMatch(boolean acceptOnMatch) {
this.acceptOnMatch = acceptOnMatch;
}
/**
* Gets whether an event within the timespan should be accepted or denied.
* @return true if matching event should be accepted.
*/
public synchronized boolean getAcceptOnMatch() {
return acceptOnMatch;
}
/** {@inheritDoc} */
public int decide(final LoggingEvent event) {
calendar.setTimeInMillis(event.timeStamp);
//
// get apparent number of milliseconds since midnight
// (ignores extra or missing hour on daylight time changes).
//
long apparentOffset = calendar.get(Calendar.HOUR_OF_DAY) * HOUR_MS +
calendar.get(Calendar.MINUTE) * MINUTE_MS +
calendar.get(Calendar.SECOND) * SECOND_MS +
calendar.get(Calendar.MILLISECOND);
if (apparentOffset >= start && apparentOffset < end) {
if (acceptOnMatch) {
return Filter.ACCEPT;
} else {
return Filter.DENY;
}
}
return Filter.NEUTRAL;
}
}
apache-log4j-extras1.2-1.2.17/src/main/java/org/apache/log4j/pattern/ 0000775 0000000 0000000 00000000000 12527427642 0024740 5 ustar 00root root 0000000 0000000 apache-log4j-extras1.2-1.2.17/src/main/java/org/apache/log4j/pattern/ExtrasFormattingInfo.java 0000664 0000000 0000000 00000010514 12527427642 0031721 0 ustar 00root root 0000000 0000000 /*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.log4j.pattern;
/**
* Modifies the output of a pattern converter for a specified minimum
* and maximum width and alignment.
*
*
* @author Jim Cakalic
* @author Ceki Gülcü
* @author Curt Arnold
*
*/
public final class ExtrasFormattingInfo {
/**
* Array of spaces.
*/
private static final char[] SPACES =
new char[] { ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ' };
/**
* Default instance.
*/
private static final ExtrasFormattingInfo DEFAULT =
new ExtrasFormattingInfo(false, 0, Integer.MAX_VALUE);
/**
* Minimum length.
*/
private final int minLength;
/**
* Maximum length.
*/
private final int maxLength;
/**
* Alignment.
*/
private final boolean leftAlign;
/**
* Right truncation.
* @since 1.2.17
*/
private final boolean rightTruncate;
/**
* Creates new instance.
* @param leftAlign left align if true.
* @param minLength minimum length.
* @param maxLength maximum length.
* @deprecated since 1.2.17
*/
public ExtrasFormattingInfo(
final boolean leftAlign,
final int minLength,
final int maxLength) {
this.leftAlign = leftAlign;
this.minLength = minLength;
this.maxLength = maxLength;
this.rightTruncate = false;
}
/**
* Creates new instance.
* @param leftAlign left align if true.
* @param rightTruncate right truncate if true.
* @param minLength minimum length.
* @param maxLength maximum length.
* @since 1.2.17
*/
public ExtrasFormattingInfo(
final boolean leftAlign,
final boolean rightTruncate,
final int minLength,
final int maxLength) {
this.leftAlign = leftAlign;
this.minLength = minLength;
this.maxLength = maxLength;
this.rightTruncate = rightTruncate;
}
/**
* Gets default instance.
* @return default instance.
*/
public static ExtrasFormattingInfo getDefault() {
return DEFAULT;
}
/**
* Determine if left aligned.
* @return true if left aligned.
*/
public boolean isLeftAligned() {
return leftAlign;
}
/**
* Determine if right truncated.
* @return true if right truncated.
* @since 1.2.17
*/
public boolean isRightTruncated() {
return rightTruncate;
}
/**
* Get minimum length.
* @return minimum length.
*/
public int getMinLength() {
return minLength;
}
/**
* Get maximum length.
* @return maximum length.
*/
public int getMaxLength() {
return maxLength;
}
/**
* Adjust the content of the buffer based on the specified lengths and alignment.
*
* @param fieldStart start of field in buffer.
* @param buffer buffer to be modified.
*/
public void format(final int fieldStart, final StringBuffer buffer) {
final int rawLength = buffer.length() - fieldStart;
if (rawLength > maxLength) {
if(rightTruncate) {
buffer.setLength(fieldStart + maxLength);
} else {
buffer.delete(fieldStart, buffer.length() - maxLength);
}
} else if (rawLength < minLength) {
if (leftAlign) {
final int fieldEnd = buffer.length();
buffer.setLength(fieldStart + minLength);
for (int i = fieldEnd; i < buffer.length(); i++) {
buffer.setCharAt(i, ' ');
}
} else {
int padLength = minLength - rawLength;
for (; padLength > 8; padLength -= 8) {
buffer.insert(fieldStart, SPACES);
}
buffer.insert(fieldStart, SPACES, 0, padLength);
}
}
}
}
apache-log4j-extras1.2-1.2.17/src/main/java/org/apache/log4j/pattern/ExtrasPatternParser.java 0000664 0000000 0000000 00000047436 12527427642 0031602 0 ustar 00root root 0000000 0000000 /*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.log4j.pattern;
import org.apache.log4j.helpers.Loader;
import org.apache.log4j.helpers.LogLog;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
// Contributors: Nelson Minar <(nelson@monkey.org>
// Igor E. Poteryaev It is this class that parses conversion patterns and creates
* a chained list of {@link PatternConverter PatternConverters}.
*
* @author James P. Cakalic
* @author Ceki Gülcü
* @author Anders Kristensen
* @author Paul Smith
* @author Curt Arnold
*
*/
public final class ExtrasPatternParser {
/**
* Escape character for format specifier.
*/
private static final char ESCAPE_CHAR = '%';
/**
* Literal state.
*/
private static final int LITERAL_STATE = 0;
/**
* In converter name state.
*/
private static final int CONVERTER_STATE = 1;
/**
* Dot state.
*/
private static final int DOT_STATE = 3;
/**
* Min state.
*/
private static final int MIN_STATE = 4;
/**
* Max state.
*/
private static final int MAX_STATE = 5;
/**
* Standard format specifiers for EnhancedPatternLayout.
*/
private static final Map PATTERN_LAYOUT_RULES;
/**
* Standard format specifiers for rolling file appenders.
*/
private static final Map FILENAME_PATTERN_RULES;
static {
// We set the global rules in the static initializer of ExtrasPatternParser class
Map rules = new HashMap(17);
rules.put("c", LoggerPatternConverter.class);
rules.put("logger", LoggerPatternConverter.class);
rules.put("C", ClassNamePatternConverter.class);
rules.put("class", ClassNamePatternConverter.class);
rules.put("d", DatePatternConverter.class);
rules.put("date", DatePatternConverter.class);
rules.put("F", FileLocationPatternConverter.class);
rules.put("file", FileLocationPatternConverter.class);
rules.put("l", FullLocationPatternConverter.class);
rules.put("L", LineLocationPatternConverter.class);
rules.put("line", LineLocationPatternConverter.class);
rules.put("m", MessagePatternConverter.class);
rules.put("message", MessagePatternConverter.class);
rules.put("n", LineSeparatorPatternConverter.class);
rules.put("M", MethodLocationPatternConverter.class);
rules.put("method", MethodLocationPatternConverter.class);
rules.put("p", LevelPatternConverter.class);
rules.put("level", LevelPatternConverter.class);
rules.put("r", RelativeTimePatternConverter.class);
rules.put("relative", RelativeTimePatternConverter.class);
rules.put("t", ThreadPatternConverter.class);
rules.put("thread", ThreadPatternConverter.class);
rules.put("x", NDCPatternConverter.class);
rules.put("ndc", NDCPatternConverter.class);
rules.put("X", PropertiesPatternConverter.class);
rules.put("properties", PropertiesPatternConverter.class);
rules.put("sn", SequenceNumberPatternConverter.class);
rules.put("sequenceNumber", SequenceNumberPatternConverter.class);
rules.put("throwable", ThrowableInformationPatternConverter.class);
PATTERN_LAYOUT_RULES = new ReadOnlyMap(rules);
Map fnameRules = new HashMap(4);
fnameRules.put("d", FileDatePatternConverter.class);
fnameRules.put("date", FileDatePatternConverter.class);
fnameRules.put("i", IntegerPatternConverter.class);
fnameRules.put("index", IntegerPatternConverter.class);
FILENAME_PATTERN_RULES = new ReadOnlyMap(fnameRules);
}
/**
* Private constructor.
*/
private ExtrasPatternParser() {
}
/**
* Get standard format specifiers for EnhancedPatternLayout.
* @return read-only map of format converter classes keyed by format specifier strings.
*/
public static Map getPatternLayoutRules() {
return PATTERN_LAYOUT_RULES;
}
/**
* Get standard format specifiers for rolling file appender file specification.
* @return read-only map of format converter classes keyed by format specifier strings.
*/
public static Map getFileNamePatternRules() {
return FILENAME_PATTERN_RULES;
}
/** Extract the converter identifier found at position i.
*
* After this function returns, the variable i will point to the
* first char after the end of the converter identifier.
*
* If i points to a char which is not a character acceptable at the
* start of a unicode identifier, the value null is returned.
*
* @param lastChar last processed character.
* @param pattern format string.
* @param i current index into pattern format.
* @param convBuf buffer to receive conversion specifier.
* @param currentLiteral literal to be output in case format specifier in unrecognized.
* @return position in pattern after converter.
*/
private static int extractConverter(
char lastChar, final String pattern, int i, final StringBuffer convBuf,
final StringBuffer currentLiteral) {
convBuf.setLength(0);
// When this method is called, lastChar points to the first character of the
// conversion word. For example:
// For "%hello" lastChar = 'h'
// For "%-5hello" lastChar = 'h'
//System.out.println("lastchar is "+lastChar);
if (!Character.isUnicodeIdentifierStart(lastChar)) {
return i;
}
convBuf.append(lastChar);
while (
(i < pattern.length())
&& Character.isUnicodeIdentifierPart(pattern.charAt(i))) {
convBuf.append(pattern.charAt(i));
currentLiteral.append(pattern.charAt(i));
//System.out.println("conv buffer is now ["+convBuf+"].");
i++;
}
return i;
}
/**
* Extract options.
* @param pattern conversion pattern.
* @param i start of options.
* @param options array to receive extracted options
* @return position in pattern after options.
*/
private static int extractOptions(String pattern, int i, List options) {
while ((i < pattern.length()) && (pattern.charAt(i) == '{')) {
int end = pattern.indexOf('}', i);
if (end == -1) {
break;
}
String r = pattern.substring(i + 1, end);
options.add(r);
i = end + 1;
}
return i;
}
/**
* Parse a format specifier.
* @param pattern pattern to parse.
* @param patternConverters list to receive pattern converters.
* @param formattingInfos list to receive field specifiers corresponding to pattern converters.
* @param converterRegistry map of user-supported pattern converters keyed by format specifier, may be null.
* @param rules map of stock pattern converters keyed by format specifier.
*/
public static void parse(
final String pattern, final List patternConverters,
final List formattingInfos, final Map converterRegistry, final Map rules) {
if (pattern == null) {
throw new NullPointerException("pattern");
}
StringBuffer currentLiteral = new StringBuffer(32);
int patternLength = pattern.length();
int state = LITERAL_STATE;
char c;
int i = 0;
ExtrasFormattingInfo formattingInfo = ExtrasFormattingInfo.getDefault();
while (i < patternLength) {
c = pattern.charAt(i++);
switch (state) {
case LITERAL_STATE:
// In literal state, the last char is always a literal.
if (i == patternLength) {
currentLiteral.append(c);
continue;
}
if (c == ESCAPE_CHAR) {
// peek at the next char.
switch (pattern.charAt(i)) {
case ESCAPE_CHAR:
currentLiteral.append(c);
i++; // move pointer
break;
default:
if (currentLiteral.length() != 0) {
patternConverters.add(
new LiteralPatternConverter(currentLiteral.toString()));
formattingInfos.add(ExtrasFormattingInfo.getDefault());
}
currentLiteral.setLength(0);
currentLiteral.append(c); // append %
state = CONVERTER_STATE;
formattingInfo = ExtrasFormattingInfo.getDefault();
}
} else {
currentLiteral.append(c);
}
break;
case CONVERTER_STATE:
currentLiteral.append(c);
switch (c) {
case '-':
formattingInfo =
new ExtrasFormattingInfo(
true,
formattingInfo.isRightTruncated(),
formattingInfo.getMinLength(),
formattingInfo.getMaxLength());
break;
case '!':
formattingInfo =
new ExtrasFormattingInfo(
formattingInfo.isLeftAligned(),
true,
formattingInfo.getMinLength(),
formattingInfo.getMaxLength());
break;
case '.':
state = DOT_STATE;
break;
default:
if ((c >= '0') && (c <= '9')) {
formattingInfo =
new ExtrasFormattingInfo(
formattingInfo.isLeftAligned(),
formattingInfo.isRightTruncated(),
c - '0',
formattingInfo.getMaxLength());
state = MIN_STATE;
} else {
i = finalizeConverter(
c, pattern, i, currentLiteral, formattingInfo,
converterRegistry, rules, patternConverters, formattingInfos);
// Next pattern is assumed to be a literal.
state = LITERAL_STATE;
formattingInfo = ExtrasFormattingInfo.getDefault();
currentLiteral.setLength(0);
}
} // switch
break;
case MIN_STATE:
currentLiteral.append(c);
if ((c >= '0') && (c <= '9')) {
formattingInfo =
new ExtrasFormattingInfo(
formattingInfo.isLeftAligned(),
formattingInfo.isRightTruncated(),
(formattingInfo.getMinLength() * 10) + (c - '0'),
formattingInfo.getMaxLength());
} else if (c == '.') {
state = DOT_STATE;
} else {
i = finalizeConverter(
c, pattern, i, currentLiteral, formattingInfo,
converterRegistry, rules, patternConverters, formattingInfos);
state = LITERAL_STATE;
formattingInfo = ExtrasFormattingInfo.getDefault();
currentLiteral.setLength(0);
}
break;
case DOT_STATE:
currentLiteral.append(c);
if ((c >= '0') && (c <= '9')) {
formattingInfo =
new ExtrasFormattingInfo(
formattingInfo.isLeftAligned(),
formattingInfo.isRightTruncated(),
formattingInfo.getMinLength(),
c - '0');
state = MAX_STATE;
} else {
LogLog.error(
"Error occured in position " + i
+ ".\n Was expecting digit, instead got char \"" + c + "\".");
state = LITERAL_STATE;
}
break;
case MAX_STATE:
currentLiteral.append(c);
if ((c >= '0') && (c <= '9')) {
formattingInfo =
new ExtrasFormattingInfo(
formattingInfo.isLeftAligned(),
formattingInfo.isRightTruncated(),
formattingInfo.getMinLength(),
(formattingInfo.getMaxLength() * 10) + (c - '0'));
} else {
i = finalizeConverter(
c, pattern, i, currentLiteral, formattingInfo,
converterRegistry, rules, patternConverters, formattingInfos);
state = LITERAL_STATE;
formattingInfo = ExtrasFormattingInfo.getDefault();
currentLiteral.setLength(0);
}
break;
} // switch
}
// while
if (currentLiteral.length() != 0) {
patternConverters.add(
new LiteralPatternConverter(currentLiteral.toString()));
formattingInfos.add(ExtrasFormattingInfo.getDefault());
}
}
/**
* Creates a new PatternConverter.
*
*
* @param converterId converterId.
* @param currentLiteral literal to be used if converter is unrecognized or following converter
* if converterId contains extra characters.
* @param converterRegistry map of user-supported pattern converters keyed by format specifier, may be null.
* @param rules map of stock pattern converters keyed by format specifier.
* @param options converter options.
* @return converter or null.
*/
private static PatternConverter createConverter(
final String converterId, final StringBuffer currentLiteral,
final Map converterRegistry, final Map rules, final List options) {
String converterName = converterId;
Object converterObj = null;
for (int i = converterId.length(); (i > 0) && (converterObj == null);
i--) {
converterName = converterName.substring(0, i);
if (converterRegistry != null) {
converterObj = converterRegistry.get(converterName);
}
if ((converterObj == null) && (rules != null)) {
converterObj = rules.get(converterName);
}
}
if (converterObj == null) {
LogLog.error("Unrecognized format specifier [" + converterId + "]");
return null;
}
Class converterClass;
if (converterObj instanceof Class) {
converterClass = (Class) converterObj;
} else {
if (converterObj instanceof String) {
try {
converterClass = Loader.loadClass((String) converterObj);
} catch (ClassNotFoundException ex) {
LogLog.warn(
"Class for conversion pattern %" + converterName + " not found",
ex);
return null;
}
} else {
LogLog.warn(
"Bad map entry for conversion pattern %" + converterName + ".");
return null;
}
}
try {
Method factory =
converterClass.getMethod(
"newInstance",
new Class[] {
Class.forName("[Ljava.lang.String;")
});
String[] optionsArray = new String[options.size()];
optionsArray = (String[]) options.toArray(optionsArray);
Object newObj =
factory.invoke(null, new Object[] { optionsArray });
if (newObj instanceof PatternConverter) {
currentLiteral.delete(
0,
currentLiteral.length()
- (converterId.length() - converterName.length()));
return (PatternConverter) newObj;
} else {
LogLog.warn(
"Class " + converterClass.getName()
+ " does not extend PatternConverter.");
}
} catch (Exception ex) {
LogLog.error("Error creating converter for " + converterId, ex);
try {
//
// try default constructor
PatternConverter pc = (PatternConverter) converterClass.newInstance();
currentLiteral.delete(
0,
currentLiteral.length()
- (converterId.length() - converterName.length()));
return pc;
} catch (Exception ex2) {
LogLog.error("Error creating converter for " + converterId, ex2);
}
}
return null;
}
/**
* Processes a format specifier sequence.
*
* @param c initial character of format specifier.
* @param pattern conversion pattern
* @param i current position in conversion pattern.
* @param currentLiteral current literal.
* @param formattingInfo current field specifier.
* @param converterRegistry map of user-provided pattern converters keyed by format specifier, may be null.
* @param rules map of stock pattern converters keyed by format specifier.
* @param patternConverters list to receive parsed pattern converter.
* @param formattingInfos list to receive corresponding field specifier.
* @return position after format specifier sequence.
*/
private static int finalizeConverter(
char c, String pattern, int i,
final StringBuffer currentLiteral, final ExtrasFormattingInfo formattingInfo,
final Map converterRegistry, final Map rules, final List patternConverters,
final List formattingInfos) {
StringBuffer convBuf = new StringBuffer();
i = extractConverter(c, pattern, i, convBuf, currentLiteral);
String converterId = convBuf.toString();
List options = new ArrayList();
i = extractOptions(pattern, i, options);
PatternConverter pc =
createConverter(
converterId, currentLiteral, converterRegistry, rules, options);
if (pc == null) {
StringBuffer msg;
if (converterId.length() == 0) {
msg =
new StringBuffer("Empty conversion specifier starting at position ");
} else {
msg = new StringBuffer("Unrecognized conversion specifier [");
msg.append(converterId);
msg.append("] starting at position ");
}
msg.append(Integer.toString(i));
msg.append(" in conversion pattern.");
LogLog.error(msg.toString());
patternConverters.add(
new LiteralPatternConverter(currentLiteral.toString()));
formattingInfos.add(ExtrasFormattingInfo.getDefault());
} else {
patternConverters.add(pc);
formattingInfos.add(formattingInfo);
if (currentLiteral.length() > 0) {
patternConverters.add(
new LiteralPatternConverter(currentLiteral.toString()));
formattingInfos.add(ExtrasFormattingInfo.getDefault());
}
}
currentLiteral.setLength(0);
return i;
}
/**
* The class wraps another Map but throws exceptions on any attempt to modify the map.
*/
private static class ReadOnlyMap implements Map {
/**
* Wrapped map.
*/
private final Map map;
/**
* Constructor
* @param src source map.
*/
public ReadOnlyMap(Map src) {
map = src;
}
/**
* {@inheritDoc}
*/
public void clear() {
throw new UnsupportedOperationException();
}
/**
* {@inheritDoc}
*/
public boolean containsKey(Object key) {
return map.containsKey(key);
}
/**
* {@inheritDoc}
*/
public boolean containsValue(Object value) {
return map.containsValue(value);
}
/**
* {@inheritDoc}
*/
public Set entrySet() {
return map.entrySet();
}
/**
* {@inheritDoc}
*/
public Object get(Object key) {
return map.get(key);
}
/**
* {@inheritDoc}
*/
public boolean isEmpty() {
return map.isEmpty();
}
/**
* {@inheritDoc}
*/
public Set keySet() {
return map.keySet();
}
/**
* {@inheritDoc}
*/
public Object put(Object key, Object value) {
throw new UnsupportedOperationException();
}
/**
* {@inheritDoc}
*/
public void putAll(Map t) {
throw new UnsupportedOperationException();
}
/**
* {@inheritDoc}
*/
public Object remove(Object key) {
throw new UnsupportedOperationException();
}
/**
* {@inheritDoc}
*/
public int size() {
return map.size();
}
/**
* {@inheritDoc}
*/
public Collection values() {
return map.values();
}
}
}
apache-log4j-extras1.2-1.2.17/src/main/java/org/apache/log4j/pattern/package.html 0000664 0000000 0000000 00000001715 12527427642 0027225 0 ustar 00root root 0000000 0000000
Provides classes implementing format specifiers in conversion patterns.
* NOTE: This receiver cannot yet be created through Chainsaw's receiver panel.
* It must be created through an XML configuration file.
*
* This receiver supports database configuration via ConnectionSource, in the
* org.apache.log4j.db package: DriverManagerConnectionSource,
* DataSourceConnectionSource, JNDIConnectionSource
*
* This database receiver differs from DBReceiver in that this receiver relies
* on custom SQL to retrieve logging event data, where DBReceiver requires the
* use of a log4j-defined schema.
*
* A 'refreshMillis' int parameter controls SQL execution. If 'refreshMillis' is
* zero (the default), the receiver will run only one time. If it is set to any
* other numeric value, the SQL will be executed on a recurring basis every
* 'refreshMillis' milliseconds.
*
* The receiver closes the connection and acquires a new connection on each
* execution of the SQL (use pooled connections if possible).
*
* If the SQL will be executing on a recurring basis, specify the IDField param -
* the column name holding the unique identifier (int) representing the logging
* event.
*
* As events are retrieved, the column represented by IDField is examined and
* the largest value is held and used by the next execution of the SQL statement
* to avoid retrieving previously processed events.
*
* As an example, the IDField references a 'COUNTER' (int, auto-increment,
* unique) column. The first execution of the SQL statement returns 500 rows,
* with a final value in the COUNTER field of 500.
*
* The SQL statement is manipulated prior to the next execution, adding ' WHERE
* COUNTER > 500' to the statement to avoid retrieval of previously processed
* events.
*
* The select statement must provide ALL fields which define a LoggingEvent.
*
* The SQL statement MUST include the columns: LOGGER, TIMESTAMP, LEVEL, THREAD,
* MESSAGE, NDC, MDC, CLASS, METHOD, FILE, LINE, PROPERTIES, THROWABLE
*
* Use ' AS ' in the SQL statement to alias the SQL's column names to match your
* database schema. (see example below).
*
* Include all fields in the SQL statement, even if you don't have data for the
* field (specify an empty string as the value for columns which you don't have
* data).
*
* The TIMESTAMP column must be a datetime.
*
* Both a PROPERTIES column and an MDC column are supported. These fields
* represent Maps on the logging event, but require the use of string
* concatenation database functions to hold the (possibly multiple) name/value
* pairs in the column.
*
* For example, to include both 'userid' and 'lastname' properties in the
* logging event (from either the PROPERTIES or MDC columns), the name/value
* pairs must be concatenated together by your database.
*
* The resulting PROPERTIES or MDC column must have data in this format: {{name,
* value, name2, value2}}
*
* The resulting PROPERTIES column would contain this text: {{userid, someone,
* lastname, mylastname}}
*
* Here is an example of concatenating a PROPERTIES or MDC column using MySQL's
* concat function, where the 'application' and 'hostname' parameters were fixed
* text, but the 'log4jid' key's value is the value of the COUNTER column:
*
* concat("{{application,databaselogs,hostname,mymachine,log4jid,", COUNTER,
* "}}") as PROPERTIES
*
* log4jid is a special property that is used by Chainsaw to represent an 'ID'
* field. Specify this property to ensure you can map events in Chainsaw to
* events in the database if you need to go back and view events at a later time
* or save the events to XML for later analysis.
*
* Here is a complete MySQL SQL statement which can be used to provide events to
* Chainsaw (note how in the example below, there is no column in logtable representing the throwable, so an
* empty string is passed in and an ALIAS is still defined):
*
* select myloggercolumn as LOGGER, mytimestampcolumn as TIMESTAMP, mylevelcolumn as LEVEL, mythreadcolumn as
* THREAD, mymessagecolumn as MESSAGE, myndccolumn as NDC, mymdccolumn as MDC, myclasscolumn as CLASS, mymethodcolumn as
* METHOD, myfilecolumn as FILE, mylinecolumn as LINE,
* concat("{{application,databaselogs,hostname,mymachine, log4jid,",
* COUNTER,"}}") as PROPERTIES, "" as THROWABLE from logtable
*
* @author Scott Deboy
*/
public class CustomSQLDBReceiver extends Receiver implements Pauseable, UnrecognizedElementHandler {
protected volatile Connection connection = null;
protected String sqlStatement = "";
/**
* By default we refresh data every 1000 milliseconds.
*
* @see #setRefreshMillis
*/
static int DEFAULT_REFRESH_MILLIS = 1000;
int refreshMillis = DEFAULT_REFRESH_MILLIS;
protected String idField = null;
int lastID = -1;
private static final String WHERE_CLAUSE = " WHERE ";
private static final String AND_CLAUSE = " AND ";
private boolean whereExists = false;
private boolean paused = false;
private ConnectionSource connectionSource;
public static final String LOG4J_ID_KEY = "log4jid";
private CustomReceiverJob customReceiverJob;
public void activateOptions() {
if(connectionSource == null) {
throw new IllegalStateException(
"CustomSQLDBReceiver cannot function without a connection source");
}
whereExists = (sqlStatement.toUpperCase().indexOf(WHERE_CLAUSE) > -1);
customReceiverJob = new CustomReceiverJob();
if(this.repository == null) {
throw new IllegalStateException(
"CustomSQLDBReceiver cannot function without a reference to its owning repository");
}
if (repository instanceof LoggerRepositoryEx) {
Scheduler scheduler = ((LoggerRepositoryEx) repository).getScheduler();
scheduler.schedule(
customReceiverJob, System.currentTimeMillis() + 500, refreshMillis);
}
}
void closeConnection() {
if (connection != null) {
try {
// LogLog.warn("closing the connection. ", new Exception("x"));
connection.close();
} catch (SQLException sqle) {
// nothing we can do here
}
}
}
public void setRefreshMillis(int refreshMillis) {
this.refreshMillis = refreshMillis;
}
public int getRefreshMillis() {
return refreshMillis;
}
/**
* @return Returns the connectionSource.
*/
public ConnectionSource getConnectionSource() {
return connectionSource;
}
/**
* @param connectionSource
* The connectionSource to set.
*/
public void setConnectionSource(ConnectionSource connectionSource) {
this.connectionSource = connectionSource;
}
public void close() {
try {
if ((connection != null) && !connection.isClosed()) {
connection.close();
}
} catch (SQLException e) {
e.printStackTrace();
} finally {
connection = null;
}
}
public void finalize() throws Throwable {
super.finalize();
close();
}
/*
* (non-Javadoc)
*
* @see org.apache.log4j.plugins.Plugin#shutdown()
*/
public void shutdown() {
getLogger().info("removing receiverJob from the Scheduler.");
if(this.repository instanceof LoggerRepositoryEx) {
Scheduler scheduler = ((LoggerRepositoryEx) repository).getScheduler();
scheduler.delete(customReceiverJob);
}
lastID = -1;
}
public void setSql(String s) {
sqlStatement = s;
}
public String getSql() {
return sqlStatement;
}
public void setIDField(String id) {
idField = id;
}
public String getIDField() {
return idField;
}
public synchronized void setPaused(boolean p) {
paused = p;
}
public synchronized boolean isPaused() {
return paused;
}
class CustomReceiverJob implements Job {
public void execute() {
int oldLastID = lastID;
try {
connection = connectionSource.getConnection();
Statement statement = connection.createStatement();
Logger eventLogger = null;
long timeStamp = 0L;
String level = null;
String threadName = null;
Object message = null;
String ndc = null;
Hashtable mdc = null;
String[] throwable = null;
String className = null;
String methodName = null;
String fileName = null;
String lineNumber = null;
Hashtable properties = null;
String currentSQLStatement = sqlStatement;
if (whereExists) {
currentSQLStatement = sqlStatement + AND_CLAUSE + idField
+ " > " + lastID;
} else {
currentSQLStatement = sqlStatement + WHERE_CLAUSE + idField
+ " > " + lastID;
}
ResultSet rs = statement.executeQuery(currentSQLStatement);
int i = 0;
while (rs.next()) {
// add a small break every 1000 received events
if (++i == 1000) {
synchronized (this) {
try {
// add a delay
wait(300);
} catch (InterruptedException ie) {
}
i = 0;
}
}
eventLogger = Logger.getLogger(rs.getString("LOGGER"));
timeStamp = rs.getTimestamp("TIMESTAMP").getTime();
level = rs.getString("LEVEL");
threadName = rs.getString("THREAD");
message = rs.getString("MESSAGE");
ndc = rs.getString("NDC");
String mdcString = rs.getString("MDC");
mdc = new Hashtable();
if (mdcString != null) {
// support MDC being wrapped in {{name, value}}
// or
// just name, value
if ((mdcString.indexOf("{{") > -1)
&& (mdcString.indexOf("}}") > -1)) {
mdcString = mdcString
.substring(mdcString.indexOf("{{") + 2,
mdcString.indexOf("}}"));
}
StringTokenizer tok = new StringTokenizer(mdcString,
",");
while (tok.countTokens() > 1) {
mdc.put(tok.nextToken(), tok.nextToken());
}
}
throwable = new String[] { rs.getString("THROWABLE") };
className = rs.getString("CLASS");
methodName = rs.getString("METHOD");
fileName = rs.getString("FILE");
lineNumber = rs.getString("LINE");
// if properties are provided in the
// SQL they can be used here (for example, to route
// events to a unique tab in
// Chainsaw if the machinename and/or appname
// property
// are set)
String propertiesString = rs.getString("PROPERTIES");
properties = new Hashtable();
if (propertiesString != null) {
// support properties being wrapped in {{name,
// value}} or just name, value
if ((propertiesString.indexOf("{{") > -1)
&& (propertiesString.indexOf("}}") > -1)) {
propertiesString = propertiesString.substring(
propertiesString.indexOf("{{") + 2,
propertiesString.indexOf("}}"));
}
StringTokenizer tok2 = new StringTokenizer(
propertiesString, ",");
while (tok2.countTokens() > 1) {
String tokenName = tok2.nextToken();
String value = tok2.nextToken();
if (tokenName.equals(LOG4J_ID_KEY)) {
try {
int thisInt = Integer.parseInt(value);
value = String.valueOf(thisInt);
if (thisInt > lastID) {
lastID = thisInt;
}
} catch (Exception e) {
}
}
properties.put(tokenName, value);
}
}
Level levelImpl = Level.toLevel(level);
LocationInfo locationInfo = new LocationInfo(fileName,
className, methodName, lineNumber);
ThrowableInformation throwableInfo = new ThrowableInformation(
throwable);
properties.putAll(mdc);
LoggingEvent event = new LoggingEvent(eventLogger.getName(),
eventLogger, timeStamp, levelImpl, message,
threadName,
throwableInfo,
ndc,
locationInfo,
properties);
doPost(event);
}
//log when rows are retrieved
if (lastID != oldLastID) {
getLogger().debug("lastID: " + lastID);
oldLastID = lastID;
}
statement.close();
statement = null;
} catch (SQLException sqle) {
getLogger()
.error("*************Problem receiving events", sqle);
} finally {
closeConnection();
}
// if paused, loop prior to executing sql query
synchronized (this) {
while (isPaused()) {
try {
wait(1000);
} catch (InterruptedException ie) {
}
}
}
}
}
/**
* {@inheritDoc}
*/
public boolean parseUnrecognizedElement(Element element, Properties props) throws Exception {
if ("connectionSource".equals(element.getNodeName())) {
Object instance =
DOMConfigurator.parseElement(element, props, ConnectionSource.class);
if (instance instanceof ConnectionSource) {
ConnectionSource source = (ConnectionSource) instance;
source.activateOptions();
setConnectionSource(source);
}
return true;
}
return false;
}
}
apache-log4j-extras1.2-1.2.17/src/main/java/org/apache/log4j/receivers/db/DBHelper.java 0000664 0000000 0000000 00000003712 12527427642 0030132 0 ustar 00root root 0000000 0000000 /*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.log4j.receivers.db;
import org.apache.log4j.spi.LoggingEvent;
import java.sql.Connection;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Set;
/**
* @author Ceki Gülcü
*
*/
public class DBHelper {
public final static short PROPERTIES_EXIST = 0x01;
public final static short EXCEPTION_EXISTS = 0x02;
public static short computeReferenceMask(LoggingEvent event) {
short mask = 0;
Set propertiesKeys = event.getPropertyKeySet();
if(propertiesKeys.size() > 0) {
mask = PROPERTIES_EXIST;
}
String[] strRep = event.getThrowableStrRep();
if(strRep != null) {
mask |= EXCEPTION_EXISTS;
}
return mask;
}
static public void closeConnection(Connection connection) {
if(connection != null) {
try {
connection.close();
} catch(SQLException sqle) {
// static utility classes should not log without an explicit repository
// reference
}
}
}
public static void closeStatement(Statement statement) {
if(statement != null) {
try {
statement.close();
} catch(SQLException sqle) {
}
}
}
}
apache-log4j-extras1.2-1.2.17/src/main/java/org/apache/log4j/receivers/db/DBReceiver.java 0000664 0000000 0000000 00000010062 12527427642 0030453 0 ustar 00root root 0000000 0000000 /*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.log4j.receivers.db;
import org.apache.log4j.component.plugins.Pauseable;
import org.apache.log4j.component.plugins.Receiver;
import org.apache.log4j.component.scheduler.Scheduler;
import org.apache.log4j.component.spi.LoggerRepositoryEx;
import org.apache.log4j.xml.DOMConfigurator;
import org.apache.log4j.xml.UnrecognizedElementHandler;
import org.w3c.dom.Element;
import java.util.Properties;
/**
*
* @author Scott Deboy
*
* @author Ray DeCampo
* @author Ceki Gülcü
*/
public class DataSourceConnectionSource extends ConnectionSourceSkeleton
implements UnrecognizedElementHandler {
private DataSource dataSource;
public void activateOptions() {
//LogLog.debug("**********DataSourceConnectionSource.activateOptions called");
if (dataSource == null) {
getLogger().warn("WARNING: No data source specified");
} else {
Connection connection = null;
try {
connection = getConnection();
} catch(SQLException se) {
getLogger().warn("Could not get a connection to discover the dialect to use.", se);
}
if(connection != null) {
discoverConnnectionProperties();
}
if(!supportsGetGeneratedKeys() && getSQLDialectCode() == ConnectionSource.UNKNOWN_DIALECT) {
getLogger().warn("Connection does not support GetGeneratedKey method and could not discover the dialect.");
}
}
}
/**
* @see org.apache.log4j.receivers.db.ConnectionSource#getConnection()
*/
public Connection getConnection() throws SQLException {
if (dataSource == null) {
getLogger().error("WARNING: No data source specified");
return null;
}
if (getUser() == null) {
return dataSource.getConnection();
} else {
return dataSource.getConnection(getUser(), getPassword());
}
}
public DataSource getDataSource() {
return dataSource;
}
public void setDataSource(DataSource dataSource) {
this.dataSource = dataSource;
}
/**
* {@inheritDoc}
*/
public boolean parseUnrecognizedElement(Element element, Properties props) throws Exception {
if ("dataSource".equals(element.getNodeName())) {
Object instance =
DOMConfigurator.parseElement(element, props, DataSource.class);
if (instance instanceof DataSource) {
setDataSource((DataSource) instance);
}
return true;
}
return false;
}
}
DriverManagerConnectionSource.java 0000664 0000000 0000000 00000011033 12527427642 0034350 0 ustar 00root root 0000000 0000000 apache-log4j-extras1.2-1.2.17/src/main/java/org/apache/log4j/receivers/db /*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.log4j.receivers.db;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
/**
* The DriverManagerConnectionSource is an implementation of {@link ConnectionSource}
* that obtains the Connection in the traditional JDBC manner based on the
* connection URL.
*
* Note that this class will establish a new Connection for each call to
* {@link #getConnection()}. It is recommended that you either use a JDBC
* driver that natively supported Connection pooling or that you create
* your own implementation of {@link ConnectionSource} that taps into whatever
* pooling mechanism you are already using. (If you have access to a JNDI
* implementation that supports {@link javax.sql.DataSource}s, e.g. within
* a J2EE application server, see {@link JNDIConnectionSource}). See
* below for a configuration example that uses the
* commons-dbcp
* package from Apache.
*
* Sample configuration:
* If you do not have another connection pooling mechanism
* built into your application, you can use the
* commons-dbcp
* package from Apache:
* Sample configuration:
* Sample configuration (with username and password):
* Note that this class will obtain an {@link javax.naming.InitialContext}
* using the no-argument constructor. This will usually work when executing
* within a J2EE environment. When outside the J2EE environment, make sure
* that you provide a jndi.properties file as described by your JNDI
* provider's documentation.
*
* @author Ray DeCampo
*/
public class JNDIConnectionSource
extends ConnectionSourceSkeleton {
private String jndiLocation = null;
private DataSource dataSource = null;
/**
* @see org.apache.log4j.spi.OptionHandler#activateOptions()
*/
public void activateOptions() {
if (jndiLocation == null) {
getLogger().error("No JNDI location specified for JNDIConnectionSource.");
}
discoverConnnectionProperties();
}
/**
* @see org.apache.log4j.receivers.db.ConnectionSource#getConnection()
*/
public Connection getConnection()
throws SQLException {
Connection conn = null;
try {
if(dataSource == null) {
dataSource = lookupDataSource();
}
if (getUser() == null) {
conn = dataSource.getConnection();
} else {
conn = dataSource.getConnection(getUser(), getPassword());
}
} catch (final NamingException ne) {
getLogger().error("Error while getting data source", ne);
throw new SQLException("NamingException while looking up DataSource: " + ne.getMessage());
} catch (final ClassCastException cce) {
getLogger().error("ClassCastException while looking up DataSource.", cce);
throw new SQLException("ClassCastException while looking up DataSource: " + cce.getMessage());
}
return conn;
}
/**
* Returns the jndiLocation.
* @return String
*/
public String getJndiLocation() {
return jndiLocation;
}
/**
* Sets the jndiLocation.
* @param jndiLocation The jndiLocation to set
*/
public void setJndiLocation(String jndiLocation) {
this.jndiLocation = jndiLocation;
}
private DataSource lookupDataSource()
throws NamingException, SQLException {
DataSource ds;
Context ctx = new InitialContext();
Object obj = ctx.lookup(jndiLocation);
// PortableRemoteObject was introduced in JDK 1.3. We won't use it.
//ds = (DataSource)PortableRemoteObject.narrow(obj, DataSource.class);
ds = (DataSource) obj;
if (ds == null) {
throw new SQLException("Failed to obtain data source from JNDI location " + jndiLocation);
} else {
return ds;
}
}
}
apache-log4j-extras1.2-1.2.17/src/main/java/org/apache/log4j/receivers/db/dialect/ 0000775 0000000 0000000 00000000000 12527427642 0027244 5 ustar 00root root 0000000 0000000 apache-log4j-extras1.2-1.2.17/src/main/java/org/apache/log4j/receivers/db/dialect/HSQLDBDialect.java0000664 0000000 0000000 00000002177 12527427642 0032361 0 ustar 00root root 0000000 0000000 /*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.log4j.receivers.db.dialect;
/**
* The HSQLDB dialect.
*
* @author Ceki Gülcü
*/
public class HSQLDBDialect implements SQLDialect {
public static final String SELECT_CURRVAL = "CALL IDENTITY()";
public String getSelectInsertId() {
return SELECT_CURRVAL;
}
}
apache-log4j-extras1.2-1.2.17/src/main/java/org/apache/log4j/receivers/db/dialect/MsSQLDialect.java 0000664 0000000 0000000 00000002362 12527427642 0032337 0 ustar 00root root 0000000 0000000 /*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.log4j.receivers.db.dialect;
/**
* The MS SQL Server dialect is untested.
*
* Note that the dialect is not needed if your JDBC driver supports
* the getGeneratedKeys method introduced in JDBC 3.0 specification.
*
* @author James Stauffer
*/
public class MsSQLDialect implements SQLDialect {
public static final String SELECT_CURRVAL = "SELECT @@identity id";
public String getSelectInsertId() {
return SELECT_CURRVAL;
}
}
apache-log4j-extras1.2-1.2.17/src/main/java/org/apache/log4j/receivers/db/dialect/MySQLDialect.java 0000664 0000000 0000000 00000002114 12527427642 0032340 0 ustar 00root root 0000000 0000000 /*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.log4j.receivers.db.dialect;
/**
*
*
* @author Ceki
*
*/
public class MySQLDialect implements SQLDialect {
public static final String SELECT_LAST_INSERT_ID = "SELECT LAST_INSERT_ID()";
public String getSelectInsertId() {
return SELECT_LAST_INSERT_ID;
}
}
apache-log4j-extras1.2-1.2.17/src/main/java/org/apache/log4j/receivers/db/dialect/OracleDialect.java0000664 0000000 0000000 00000002275 12527427642 0032610 0 ustar 00root root 0000000 0000000 /*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.log4j.receivers.db.dialect;
/**
* The Oracle dialect. Tested successfully on Oracle9i Release 9.2.0.3.0 by
* James Stauffer.
*
* @author Ceki Gülcü
*/
public class OracleDialect implements SQLDialect {
public static final String SELECT_CURRVAL = "SELECT logging_event_id_seq.currval from dual";
public String getSelectInsertId() {
return SELECT_CURRVAL;
}
}
PostgreSQLDialect.java 0000664 0000000 0000000 00000002321 12527427642 0033317 0 ustar 00root root 0000000 0000000 apache-log4j-extras1.2-1.2.17/src/main/java/org/apache/log4j/receivers/db/dialect /*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.log4j.receivers.db.dialect;
/**
*
* @author ceki
*
* To change the template for this generated type comment go to
* Window>Preferences>Java>Code Generation>Code and Comments
*/
public class PostgreSQLDialect
implements SQLDialect {
public static final String SELECT_CURRVAL = "SELECT currval('logging_event_id_seq')";
public String getSelectInsertId() {
return SELECT_CURRVAL;
}
}
apache-log4j-extras1.2-1.2.17/src/main/java/org/apache/log4j/receivers/db/dialect/SQLDialect.java 0000664 0000000 0000000 00000001673 12527427642 0032043 0 ustar 00root root 0000000 0000000 /*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.log4j.receivers.db.dialect;
/**
* @author ceki
*
*/
public interface SQLDialect {
public String getSelectInsertId();
}
apache-log4j-extras1.2-1.2.17/src/main/java/org/apache/log4j/receivers/db/dialect/SybaseDialect.java0000664 0000000 0000000 00000002075 12527427642 0032627 0 ustar 00root root 0000000 0000000 /*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.log4j.receivers.db.dialect;
/**
* The Sybase dialect.
*
*/
public class SybaseDialect implements SQLDialect {
public static final String SELECT_CURRVAL = "select @@identity";
public String getSelectInsertId() {
return SELECT_CURRVAL;
}
}
apache-log4j-extras1.2-1.2.17/src/main/java/org/apache/log4j/receivers/db/dialect/Util.java 0000664 0000000 0000000 00000007542 12527427642 0031034 0 ustar 00root root 0000000 0000000 /*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.log4j.receivers.db.dialect;
import org.apache.log4j.component.spi.ComponentBase;
import org.apache.log4j.receivers.db.ConnectionSource;
import java.sql.DatabaseMetaData;
import java.sql.SQLException;
/**
*
* @author Ceki Gulcu
*
*/
public class Util extends ComponentBase {
private static final String POSTGRES_PART = "postgresql";
private static final String MYSQL_PART = "mysql";
private static final String ORACLE_PART = "oracle";
//private static final String MSSQL_PART = "mssqlserver4";
private static final String MSSQL_PART = "microsoft";
private static final String HSQL_PART = "hsql";
public static int discoverSQLDialect(DatabaseMetaData meta) {
int dialectCode = 0;
try {
String dbName = meta.getDatabaseProductName().toLowerCase();
if (dbName.indexOf(POSTGRES_PART) != -1) {
return ConnectionSource.POSTGRES_DIALECT;
} else if (dbName.indexOf(MYSQL_PART) != -1) {
return ConnectionSource.MYSQL_DIALECT;
} else if (dbName.indexOf(ORACLE_PART) != -1) {
return ConnectionSource.ORACLE_DIALECT;
} else if (dbName.indexOf(MSSQL_PART) != -1) {
return ConnectionSource.MSSQL_DIALECT;
} else if (dbName.indexOf(HSQL_PART) != -1) {
return ConnectionSource.HSQL_DIALECT;
} else {
return ConnectionSource.UNKNOWN_DIALECT;
}
} catch (SQLException sqle) {
// we can't do much here
}
return dialectCode;
}
public static SQLDialect getDialectFromCode(int dialectCode) {
SQLDialect sqlDialect = null;
switch (dialectCode) {
case ConnectionSource.POSTGRES_DIALECT:
sqlDialect = new PostgreSQLDialect();
break;
case ConnectionSource.MYSQL_DIALECT:
sqlDialect = new MySQLDialect();
break;
case ConnectionSource.ORACLE_DIALECT:
sqlDialect = new OracleDialect();
break;
case ConnectionSource.MSSQL_DIALECT:
sqlDialect = new MsSQLDialect();
break;
case ConnectionSource.HSQL_DIALECT:
sqlDialect = new HSQLDBDialect();
break;
}
return sqlDialect;
}
/**
* This method handles cases where the
* {@link DatabaseMetaData#supportsGetGeneratedKeys} method is missing in the
* JDBC driver implementation.
*/
public boolean supportsGetGeneratedKeys(DatabaseMetaData meta) {
try {
//
// invoking JDK 1.4 method by reflection
//
return ((Boolean) DatabaseMetaData.class.getMethod("supportsGetGeneratedKeys", null).invoke(meta, null)).booleanValue();
} catch(Throwable e) {
getLogger().info("Could not call supportsGetGeneratedKeys method. This may be recoverable");
return false;
}
}
/**
* This method handles cases where the
* {@link DatabaseMetaData#supportsBatchUpdates} method is missing in the
* JDBC driver implementation.
*/
public boolean supportsBatchUpdates(DatabaseMetaData meta) {
try {
return meta.supportsBatchUpdates();
} catch(Throwable e) {
getLogger().info("Missing DatabaseMetaData.supportsBatchUpdates method.");
return false;
}
}
}
apache-log4j-extras1.2-1.2.17/src/main/java/org/apache/log4j/receivers/db/dialect/db2.sql 0000664 0000000 0000000 00000004527 12527427642 0030444 0 ustar 00root root 0000000 0000000 # Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements. See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The ASF licenses this file to You under the Apache License, Version 2.0
# (the "License"); you may not use this file except in compliance with
# the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# This SQL script creates the required tables by org.apache.log4j.db.DBAppender and
# org.apache.log4j.db.DBReceiver.
#
# It is intended for IBM DB2 databases.
#
# WARNING WARNING WARNING WARNING
# =================================
# This SQL script has not been tested on an actual DB2
# instance. It may contain errors or even invalid SQL
# statements.
DROP TABLE logging_event_property;
DROP TABLE logging_event_exception;
DROP TABLE logging_event;
CREATE TABLE logging_event
(
sequence_number BIGINT NOT NULL,
timestamp BIGINT NOT NULL,
rendered_message VARCHAR(4000) NOT NULL,
logger_name VARCHAR(254) NOT NULL,
level_string VARCHAR(254) NOT NULL,
ndc VARCHAR(4000),
thread_name VARCHAR(254),
reference_flag SMALLINT,
caller_filename VARCHAR(254) NOT NULL,
caller_class VARCHAR(254) NOT NULL,
caller_method VARCHAR(254) NOT NULL,
caller_line CHAR(4) NOT NULL,
event_id INTEGER GENERATED ALWAYS AS IDENTITY (START WITH 1)
);
CREATE TABLE logging_event_property
(
event_id INTEGER NOT NULL,
mapped_key VARCHAR(254) NOT NULL,
mapped_value VARCHAR(1024),
PRIMARY KEY(event_id, mapped_key),
FOREIGN KEY (event_id) REFERENCES logging_event(event_id)
);
CREATE TABLE logging_event_exception
(
event_id INTEGER NOT NULL,
i SMALLINT NOT NULL,
trace_line VARCHAR(254) NOT NULL,
PRIMARY KEY(event_id, i),
FOREIGN KEY (event_id) REFERENCES logging_event(event_id)
);
apache-log4j-extras1.2-1.2.17/src/main/java/org/apache/log4j/receivers/db/dialect/db2l.sql 0000664 0000000 0000000 00000004260 12527427642 0030612 0 ustar 00root root 0000000 0000000 # Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements. See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The ASF licenses this file to You under the Apache License, Version 2.0
# (the "License"); you may not use this file except in compliance with
# the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# This SQL script creates the required tables by org.apache.log4j.db.DBAppender and
# org.apache.log4j.db.DBReceiver.
#
# It is intended for PostgreSQL databases.
DROP TABLE logging_event_property;
DROP TABLE logging_event_exception;
DROP TABLE logging_event;
CREATE SEQUENCE logging_event_id_seq MINVALUE 1 START 1;
CREATE TABLE logging_event
(
sequence_number BIGINT NOT NULL,
timestamp BIGINT NOT NULL,
rendered_message TEXT NOT NULL,
logger_name VARCHAR(254) NOT NULL,
level_string VARCHAR(254) NOT NULL,
ndc TEXT,
thread_name VARCHAR(254),
reference_flag SMALLINT,
caller_filename VARCHAR(254) NOT NULL,
caller_class VARCHAR(254) NOT NULL,
caller_method VARCHAR(254) NOT NULL,
caller_line CHAR(4) NOT NULL,
event_id INT IDENTITY GENERATED ALWAYS PRIMARY KEY
);
CREATE TABLE logging_event_property
(
event_id INT NOT NULL,
mapped_key VARCHAR(254) NOT NULL,
mapped_value VARCHAR(1024),
PRIMARY KEY(event_id, mapped_key),
FOREIGN KEY (event_id) REFERENCES logging_event(event_id)
);
CREATE TABLE logging_event_exception
(
event_id INT NOT NULL,
i SMALLINT NOT NULL,
trace_line VARCHAR(254) NOT NULL,
PRIMARY KEY(event_id, i),
FOREIGN KEY (event_id) REFERENCES logging_event(event_id)
);
apache-log4j-extras1.2-1.2.17/src/main/java/org/apache/log4j/receivers/db/dialect/hsqldb.sql 0000664 0000000 0000000 00000004107 12527427642 0031244 0 ustar 00root root 0000000 0000000 // Licensed to the Apache Software Foundation (ASF) under one or more
// contributor license agreements. See the NOTICE file distributed with
// this work for additional information regarding copyright ownership.
// The ASF licenses this file to You under the Apache License, Version 2.0
// (the "License"); you may not use this file except in compliance with
// the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// This SQL script creates the required tables by
// org.apache.log4j.db.DBAppender and org.apache.log4j.db.DBReceiver.
//
// It is intended for HSQLDB.
//
DROP TABLE logging_event_exception IF EXISTS;
DROP TABLE logging_event_property IF EXISTS;
DROP TABLE logging_event IF EXISTS;
CREATE TABLE logging_event
(
sequence_number BIGINT NOT NULL,
timestamp BIGINT NOT NULL,
rendered_message LONGVARCHAR NOT NULL,
logger_name VARCHAR NOT NULL,
level_string VARCHAR NOT NULL,
ndc LONGVARCHAR,
thread_name VARCHAR,
reference_flag SMALLINT,
caller_filename VARCHAR,
caller_class VARCHAR,
caller_method VARCHAR,
caller_line CHAR(4),
event_id INT NOT NULL IDENTITY
);
CREATE TABLE logging_event_property
(
event_id INT NOT NULL,
mapped_key VARCHAR(254) NOT NULL,
mapped_value LONGVARCHAR,
PRIMARY KEY(event_id, mapped_key),
FOREIGN KEY (event_id) REFERENCES logging_event(event_id)
);
CREATE TABLE logging_event_exception
(
event_id INT NOT NULL,
i SMALLINT NOT NULL,
trace_line VARCHAR NOT NULL,
PRIMARY KEY(event_id, i),
FOREIGN KEY (event_id) REFERENCES logging_event(event_id)
);
apache-log4j-extras1.2-1.2.17/src/main/java/org/apache/log4j/receivers/db/dialect/mssql.sql 0000664 0000000 0000000 00000004361 12527427642 0031130 0 ustar 00root root 0000000 0000000 -- Licensed to the Apache Software Foundation (ASF) under one or more
-- contributor license agreements. See the NOTICE file distributed with
-- this work for additional information regarding copyright ownership.
-- The ASF licenses this file to You under the Apache License, Version 2.0
-- (the "License"); you may not use this file except in compliance with
-- the License. You may obtain a copy of the License at
--
-- http://www.apache.org/licenses/LICENSE-2.0
--
-- Unless required by applicable law or agreed to in writing, software
-- distributed under the License is distributed on an "AS IS" BASIS,
-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-- See the License for the specific language governing permissions and
-- limitations under the License.
--
--
-- This SQL script creates the required tables by org.apache.log4j.db.DBAppender and
-- org.apache.log4j.db.DBReceiver.
--
-- It is intended for MS SQL Server databases. This has been tested with version 7.0.
DROP TABLE logging_event_property
DROP TABLE logging_event_exception
DROP TABLE logging_event
CREATE TABLE logging_event
(
sequence_number DECIMAL(20) NOT NULL,
timestamp DECIMAL(20) NOT NULL,
rendered_message VARCHAR(4000) NOT NULL,
logger_name VARCHAR(254) NOT NULL,
level_string VARCHAR(254) NOT NULL,
ndc VARCHAR(4000),
thread_name VARCHAR(254),
reference_flag SMALLINT,
caller_filename VARCHAR(254) NOT NULL,
caller_class VARCHAR(254) NOT NULL,
caller_method VARCHAR(254) NOT NULL,
caller_line CHAR(4) NOT NULL,
event_id INT NOT NULL identity,
PRIMARY KEY(event_id)
)
CREATE TABLE logging_event_property
(
event_id INT NOT NULL,
mapped_key VARCHAR(254) NOT NULL,
mapped_value VARCHAR(1024),
PRIMARY KEY(event_id, mapped_key),
FOREIGN KEY (event_id) REFERENCES logging_event(event_id)
)
CREATE TABLE logging_event_exception
(
event_id INT NOT NULL,
i SMALLINT NOT NULL,
trace_line VARCHAR(254) NOT NULL,
PRIMARY KEY(event_id, i),
FOREIGN KEY (event_id) REFERENCES logging_event(event_id)
)
apache-log4j-extras1.2-1.2.17/src/main/java/org/apache/log4j/receivers/db/dialect/mysql.sql 0000664 0000000 0000000 00000004364 12527427642 0031141 0 ustar 00root root 0000000 0000000 # Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements. See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The ASF licenses this file to You under the Apache License, Version 2.0
# (the "License"); you may not use this file except in compliance with
# the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
#
#
# This SQL script creates the required tables by org.apache.log4j.db.DBAppender and
# org.apache.log4j.db.DBReceiver.
#
# It is intended for MySQL databases. It has been tested on MySQL 4.1.1 with
# INNODB tables.
BEGIN;
DROP TABLE IF EXISTS logging_event_property;
DROP TABLE IF EXISTS logging_event_exception;
DROP TABLE IF EXISTS logging_event;
COMMIT;
BEGIN;
CREATE TABLE logging_event
(
sequence_number BIGINT NOT NULL,
timestamp BIGINT NOT NULL,
rendered_message TEXT NOT NULL,
logger_name VARCHAR(254) NOT NULL,
level_string VARCHAR(254) NOT NULL,
ndc TEXT,
thread_name VARCHAR(254),
reference_flag SMALLINT,
caller_filename VARCHAR(254) NOT NULL,
caller_class VARCHAR(254) NOT NULL,
caller_method VARCHAR(254) NOT NULL,
caller_line CHAR(4) NOT NULL,
event_id INT NOT NULL AUTO_INCREMENT PRIMARY KEY
);
COMMIT;
BEGIN;
CREATE TABLE logging_event_property
(
event_id INT NOT NULL,
mapped_key VARCHAR(254) NOT NULL,
mapped_value TEXT,
PRIMARY KEY(event_id, mapped_key),
FOREIGN KEY (event_id) REFERENCES logging_event(event_id)
);
COMMIT;
BEGIN;
CREATE TABLE logging_event_exception
(
event_id INT NOT NULL,
i SMALLINT NOT NULL,
trace_line VARCHAR(254) NOT NULL,
PRIMARY KEY(event_id, i),
FOREIGN KEY (event_id) REFERENCES logging_event(event_id)
);
COMMIT;
apache-log4j-extras1.2-1.2.17/src/main/java/org/apache/log4j/receivers/db/dialect/oracle.sql 0000664 0000000 0000000 00000005301 12527427642 0031231 0 ustar 00root root 0000000 0000000 -- Licensed to the Apache Software Foundation (ASF) under one or more
-- contributor license agreements. See the NOTICE file distributed with
-- this work for additional information regarding copyright ownership.
-- The ASF licenses this file to You under the Apache License, Version 2.0
-- (the "License"); you may not use this file except in compliance with
-- the License. You may obtain a copy of the License at
--
-- http://www.apache.org/licenses/LICENSE-2.0
--
-- Unless required by applicable law or agreed to in writing, software
-- distributed under the License is distributed on an "AS IS" BASIS,
-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-- See the License for the specific language governing permissions and
-- limitations under the License.
--
--
-- This SQL script creates the required tables by org.apache.log4j.db.DBAppender and
-- org.apache.log4j.db.DBReceiver.
--
-- It is intended for Oracle databases.
-- Tested successfully on Oracle9i Release 9.2.0.3.0 by James Stauffer
-- Tested successfully on Oracle9i Release by Elias Ross
-- The following lines are useful in cleaning any previous tables
--drop TRIGGER logging_event_id_seq_trig;
--drop SEQUENCE logging_event_id_seq;
--drop table logging_event_property;
--drop table logging_event_exception;
--drop table logging_event;
CREATE SEQUENCE logging_event_id_seq MINVALUE 1 START WITH 1;
CREATE TABLE logging_event
(
sequence_number NUMBER(20) NOT NULL,
timestamp NUMBER(20) NOT NULL,
rendered_message VARCHAR2(4000) NOT NULL,
logger_name VARCHAR2(254) NOT NULL,
level_string VARCHAR2(254) NOT NULL,
ndc VARCHAR2(4000),
thread_name VARCHAR2(254),
reference_flag NUMBER(5),
caller_filename VARCHAR2(254) NOT NULL,
caller_class VARCHAR2(254) NOT NULL,
caller_method VARCHAR2(254) NOT NULL,
caller_line CHAR(4) NOT NULL,
event_id NUMBER(10) PRIMARY KEY
);
CREATE OR REPLACE TRIGGER logging_event_id_seq_trig
BEFORE INSERT ON logging_event
FOR EACH ROW
BEGIN
SELECT logging_event_id_seq.nextval
INTO :new.sequence_number FROM dual;
END;
CREATE TABLE logging_event_property
(
event_id NUMBER(10) NOT NULL,
mapped_key VARCHAR2(254) NOT NULL,
mapped_value VARCHAR2(1024),
PRIMARY KEY(event_id, mapped_key),
FOREIGN KEY (event_id) REFERENCES logging_event(event_id)
);
CREATE TABLE logging_event_exception
(
event_id NUMBER(10) NOT NULL,
i NUMBER(5) NOT NULL,
trace_line VARCHAR2(254) NOT NULL,
PRIMARY KEY(event_id, i),
FOREIGN KEY (event_id) REFERENCES logging_event(event_id)
);
apache-log4j-extras1.2-1.2.17/src/main/java/org/apache/log4j/receivers/db/dialect/postgresql.sql 0000664 0000000 0000000 00000004345 12527427642 0032176 0 ustar 00root root 0000000 0000000 # Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements. See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The ASF licenses this file to You under the Apache License, Version 2.0
# (the "License"); you may not use this file except in compliance with
# the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
## This SQL script creates the required tables by org.apache.log4j.db.DBAppender and
# org.apache.log4j.db.DBReceiver.
#
# It is intended for PostgreSQL databases.
DROP TABLE logging_event_property;
DROP TABLE logging_event_exception;
DROP SEQUENCE logging_event_id_seq;
DROP TABLE logging_event;
CREATE SEQUENCE logging_event_id_seq MINVALUE 1 START 1;
CREATE TABLE logging_event
(
sequence_number BIGINT NOT NULL,
timestamp BIGINT NOT NULL,
rendered_message TEXT NOT NULL,
logger_name VARCHAR(254) NOT NULL,
level_string VARCHAR(254) NOT NULL,
ndc TEXT,
thread_name VARCHAR(254),
reference_flag SMALLINT,
caller_filename VARCHAR(254) NOT NULL,
caller_class VARCHAR(254) NOT NULL,
caller_method VARCHAR(254) NOT NULL,
caller_line CHAR(4) NOT NULL,
event_id INT DEFAULT nextval('logging_event_id_seq') PRIMARY KEY
);
CREATE TABLE logging_event_property
(
event_id INT NOT NULL,
mapped_key VARCHAR(254) NOT NULL,
mapped_value VARCHAR(1024),
PRIMARY KEY(event_id, mapped_key),
FOREIGN KEY (event_id) REFERENCES logging_event(event_id)
);
CREATE TABLE logging_event_exception
(
event_id INT NOT NULL,
i SMALLINT NOT NULL,
trace_line VARCHAR(254) NOT NULL,
PRIMARY KEY(event_id, i),
FOREIGN KEY (event_id) REFERENCES logging_event(event_id)
);
apache-log4j-extras1.2-1.2.17/src/main/java/org/apache/log4j/receivers/db/package.html 0000664 0000000 0000000 00000002565 12527427642 0030130 0 ustar 00root root 0000000 0000000
The org.apache.log4j.db package provides means to append logging events
into various databases. The persisted data can be later read back using
{@link org.apache.log4j.receivers.db.DBReceiver}.
Most popular database systems, such as PostgreSQL, MySQL, Oracle, DB2 and MsSQL
are supported.
Just as importantly, the way for obtaining JDBC connections is pluggable. Connections can
be obtained through the traditional way of DriverManager, or alternatively as a DataSource.
A DataSource can be instantiated directly or it can obtained through JNDI.
Once the event has been "posted", it will be handled by the
appenders currently configured in the LoggerRespository.
This implementation borrows heavily from the JMSSink
implementation.
@author Mark Womack
@author Paul Smith
@author Stephen Pain
*/
public class JMSReceiver extends Receiver implements MessageListener {
private boolean active = false;
protected String topicFactoryName;
protected String topicName;
protected String userId;
protected String password;
protected TopicConnection topicConnection;
protected String jndiPath;
private String remoteInfo;
private String providerUrl;
public JMSReceiver() { }
public JMSReceiver(String _topicFactoryName, String _topicName,
String _userId, String _password, String _jndiPath) {
topicFactoryName = _topicFactoryName;
topicName = _topicName;
userId = _userId;
password = _password;
jndiPath = _jndiPath;
}
/**
* Sets the path to a properties file containing
* the initial context and jndi provider url
*/
public void setJndiPath(String _jndiPath) {
jndiPath = _jndiPath;
}
/**
* Gets the path to a properties file containing
* the initial context and jndi provider url
*/
public String getJndiPath() {
return jndiPath;
}
/**
Sets the JMS topic factory name to use when creating the
JMS connection. */
public void setTopicFactoryName(String _topicFactoryName) {
topicFactoryName = _topicFactoryName;
}
/**
Gets the curernt JMS topic factory name property. */
public String getTopicFactoryName() {
return topicFactoryName;
}
/**
* Sets the JMS topic name to use when creating the
* JMS connection.
*/
public void setTopicName(String _topicName) {
topicName = _topicName;
}
/**
* Gets the curernt JMS topic name property.
*/
public String getTopicName() {
return topicName;
}
/**
Sets the user id to use when creating the
JMS connection. */
public void setUserId(String _userId) {
userId = _userId;
}
/**
* Gets the current user id property.
*/
public String getUserId() {
return userId;
}
/**
* Sets the password to use when creating the
* JMS connection.
*/
public void setPassword(String _password) {
password = _password;
}
/**
* Gets the curernt password property.
*/
public String getPassword() {
return password;
}
/**
* Returns true if the receiver is the same class and they are
* configured for the same properties, and super class also considers
* them to be equivalent. This is used by PluginRegistry when determining
* if the a similarly configured receiver is being started.
*
* @param testPlugin The plugin to test equivalency against.
* @return boolean True if the testPlugin is equivalent to this plugin.
*/
public boolean isEquivalent(Plugin testPlugin) {
// only do full check if an instance of this class
if (testPlugin instanceof JMSReceiver) {
JMSReceiver receiver = (JMSReceiver)testPlugin;
// check for same topic name and super class equivalency
return (
topicFactoryName.equals(receiver.getTopicFactoryName()) &&
(jndiPath == null || jndiPath.equals(receiver.getJndiPath())) &&
super.isEquivalent(testPlugin)
);
}
return false;
}
/**
Returns true if this receiver is active. */
public synchronized boolean isActive() {
return active;
}
/**
Sets the flag to indicate if receiver is active or not. */
protected synchronized void setActive(boolean _active) {
active = _active;
}
/**
Starts the JMSReceiver with the current options. */
public void activateOptions() {
if (!isActive()) {
try {
remoteInfo = topicFactoryName + ":" + topicName;
Context ctx = null;
if (jndiPath == null || jndiPath.equals("")) {
ctx = new InitialContext();
} else {
FileInputStream is = new FileInputStream(jndiPath);
Properties p = new Properties();
p.load(is);
is.close();
ctx = new InitialContext(p);
}
// give some more flexibility about the choice of a tab name
providerUrl = (String)ctx.getEnvironment().get(Context.PROVIDER_URL);
TopicConnectionFactory topicConnectionFactory;
topicConnectionFactory =
(TopicConnectionFactory) lookup(ctx, topicFactoryName);
if (userId != null && password != null) {
topicConnection =
topicConnectionFactory.createTopicConnection(userId, password);
} else {
topicConnection =
topicConnectionFactory.createTopicConnection();
}
TopicSession topicSession =
topicConnection.createTopicSession(false, Session.AUTO_ACKNOWLEDGE);
Topic topic = (Topic)ctx.lookup(topicName);
TopicSubscriber topicSubscriber = topicSession.createSubscriber(topic);
topicSubscriber.setMessageListener(this);
topicConnection.start();
setActive(true);
} catch(Exception e) {
setActive(false);
if (topicConnection != null) {
try {
topicConnection.close();
} catch (Exception e2) {
// do nothing
}
topicConnection = null;
}
getLogger().error("Could not start JMSReceiver.", e);
}
}
}
/**
Called when the receiver should be stopped. */
public synchronized void shutdown() {
if (isActive()) {
// mark this as no longer running
setActive(false);
if (topicConnection != null) {
try {
topicConnection.close();
} catch (Exception e) {
// do nothing
}
topicConnection = null;
}
}
}
public void onMessage(Message message) {
try {
if(message instanceof ObjectMessage) {
// get the logging event and post it to the repository
ObjectMessage objectMessage = (ObjectMessage) message;
LoggingEvent event = (LoggingEvent) objectMessage.getObject();
// store the known remote info in an event property
event.setProperty("log4j.remoteSourceInfo", remoteInfo);
event.setProperty("log4j.jmsProviderUrl", providerUrl);
doPost(event);
} else {
getLogger().warn("Received message is of type "+message.getJMSType()
+", was expecting ObjectMessage.");
}
} catch(Exception e) {
getLogger().error("Exception thrown while processing incoming message.", e);
}
}
protected Object lookup(Context ctx, String name) throws NamingException {
try {
return ctx.lookup(name);
} catch(NameNotFoundException e) {
getLogger().error("Could not find name ["+name+"].");
throw e;
}
}
}
apache-log4j-extras1.2-1.2.17/src/main/java/org/apache/log4j/receivers/net/JMSReceiverBeanInfo.java 0000664 0000000 0000000 00000003436 12527427642 0032431 0 ustar 00root root 0000000 0000000 /*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.log4j.receivers.net;
import java.beans.PropertyDescriptor;
import java.beans.SimpleBeanInfo;
/**
* BeanInfo class for the JMSReceiver.
*
* @author Paul Smith Messages are not sent as LoggingEvent objects but as text after
* applying XMLLayout.
*
* The port and remoteHost properties can be set in configuration properties.
* By setting the remoteHost to a broadcast address any number of clients can
* listen for log messages.
*
* This was inspired and really extended/copied from {@link org.apache.log4j.net.SocketAppender}. Please
* see the docs for the proper credit to the authors of that class.
*
* @author Kevin Brown
* @author Scott Deboy This will mark the appender as closed and
call then {@link #cleanUp} method.
*/
public synchronized void close() {
if (closed) {
return;
}
this.closed = true;
if (advertiseViaMulticastDNS) {
zeroConf.unadvertise();
}
cleanUp();
}
/**
Close the Socket and release the underlying
connector thread if it has been created
*/
public void cleanUp() {
if (outSocket != null) {
try {
outSocket.close();
} catch (Exception e) {
LogLog.error("Could not close outSocket.", e);
}
outSocket = null;
}
}
void connect() {
if (this.address == null) {
return;
}
try {
// First, close the previous connection if any.
cleanUp();
outSocket = new MulticastSocket();
outSocket.setTimeToLive(timeToLive);
} catch (IOException e) {
LogLog.error("Error in connect method of MulticastAppender named "+name, e);
}
}
public void append(LoggingEvent event) {
if (event == null) {
return;
}
if(locationInfo) {
event.getLocationInformation();
}
if (outSocket != null) {
event.setProperty(Constants.HOSTNAME_KEY, hostname);
if (application != null) {
event.setProperty(Constants.APPLICATION_KEY, application);
}
if(locationInfo) {
event.getLocationInformation();
}
try {
StringBuffer buf = new StringBuffer(layout.format(event));
byte[] payload;
if(encoding == null) {
payload = buf.toString().getBytes();
} else {
payload = buf.toString().getBytes(encoding);
}
DatagramPacket dp =
new DatagramPacket(payload, payload.length, address, port);
outSocket.send(dp);
} catch (IOException e) {
outSocket = null;
LogLog.warn("Detected problem with Multicast connection: " + e);
}
}
}
InetAddress getAddressByName(String host) {
try {
return InetAddress.getByName(host);
} catch (Exception e) {
LogLog.error("Could not find address of [" + host + "].", e);
return null;
}
}
/**
The RemoteHost option takes a string value which should be
the host name or ipaddress to send the multicast packets.
*/
public void setRemoteHost(String host) {
remoteHost = host;
}
/**
Returns value of the RemoteHost option.
*/
public String getRemoteHost() {
return remoteHost;
}
/**
The LocationInfo option takes a boolean value. If true,
the information sent to the remote host will include location
information. By default no location information is sent to the server.
*/
public void setLocationInfo(boolean locationInfo) {
this.locationInfo = locationInfo;
}
/**
* Returns value of the LocationInfo option.
*/
public boolean getLocationInfo() {
return locationInfo;
}
/**
The Encoding option specifies how the bytes are encoded. If this option is not specified,
the System encoding is used.
*/
public void setEncoding(String encoding) {
this.encoding = encoding;
}
/**
Returns value of the Encoding option.
*/
public String getEncoding() {
return encoding;
}
/**
The App option takes a string value which should be the name of the application getting logged.
If property was already set (via system property), don't set here.
*/
public void setApplication(String app) {
this.application = app;
}
/**
Returns value of the App option.
*/
public String getApplication() {
return application;
}
/**
The Time to live option takes a positive integer representing
the time to live value.
*/
public void setTimeToLive(int timeToLive) {
this.timeToLive = timeToLive;
}
/**
Returns value of the Time to Live option.
*/
public int getTimeToLive() {
return timeToLive;
}
/**
The Port option takes a positive integer representing
the port where multicast packets will be sent.
*/
public void setPort(int port) {
this.port = port;
}
/**
Returns value of the Port option.
*/
public int getPort() {
return port;
}
/* (non-Javadoc)
* @see org.apache.log4j.net.NetworkBased#isActive()
*/
public boolean isActive() {
// TODO handle active/inactive
return true;
}
/**
* Gets whether appender requires a layout.
* @return false
*/
public boolean requiresLayout() {
return true;
}
public boolean isAdvertiseViaMulticastDNS() {
return advertiseViaMulticastDNS;
}
public void setAdvertiseViaMulticastDNS(boolean advertiseViaMulticastDNS) {
this.advertiseViaMulticastDNS = advertiseViaMulticastDNS;
}
}
apache-log4j-extras1.2-1.2.17/src/main/java/org/apache/log4j/receivers/net/MulticastReceiver.java 0000664 0000000 0000000 00000015736 12527427642 0032351 0 ustar 00root root 0000000 0000000 /*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.log4j.receivers.net;
import org.apache.log4j.component.plugins.Pauseable;
import org.apache.log4j.component.plugins.Receiver;
import org.apache.log4j.net.ZeroConfSupport;
import org.apache.log4j.receivers.spi.Decoder;
import org.apache.log4j.spi.LoggingEvent;
import java.io.IOException;
import java.net.*;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
/**
* Multicast-based receiver. Accepts LoggingEvents encoded using
* MulticastAppender and XMLLayout. The the XML data is converted
* back to a LoggingEvent and is posted.
*
* @author Scott Deboy Once the event has been "posted", it will be handled by the
appenders currently configured in the LoggerRespository.
@author Mark Womack
@author Ceki Gülcü
@author Paul Smith (psmith@apache.org)
*/
public class SocketHubReceiver
extends Receiver implements SocketNodeEventListener, PortBased {
/**
* Default reconnection delay.
*/
static final int DEFAULT_RECONNECTION_DELAY = 30000;
/**
* Host.
*/
protected String host;
/**
* Port.
*/
protected int port;
/**
* Reconnection delay.
*/
protected int reconnectionDelay = DEFAULT_RECONNECTION_DELAY;
/**
* The MulticastDNS zone advertised by a SocketHubReceiver
*/
public static final String ZONE = "_log4j_obj_tcpconnect_receiver.local.";
/**
* Active.
*/
protected boolean active = false;
/**
* Connector.
*/
protected Connector connector;
/**
* Socket.
*/
protected SocketNode13 socketNode;
/**
* Listener list.
*/
private List listenerList = Collections.synchronizedList(new ArrayList());
private boolean advertiseViaMulticastDNS;
private ZeroConfSupport zeroConf;
/**
* Create new instance.
*/
public SocketHubReceiver() {
super();
}
/**
* Create new instance.
* @param h host
* @param p port
*/
public SocketHubReceiver(final String h,
final int p) {
super();
host = h;
port = p;
}
/**
* Create new instance.
* @param h host
* @param p port
* @param repo logger repository
*/
public SocketHubReceiver(final String h,
final int p,
final LoggerRepository repo) {
super();
host = h;
port = p;
repository = repo;
}
/**
* Adds a SocketNodeEventListener to this receiver to be notified
* of SocketNode events.
* @param l listener
*/
public void addSocketNodeEventListener(final SocketNodeEventListener l) {
listenerList.add(l);
}
/**
* Removes a specific SocketNodeEventListener from this instance
* so that it will no longer be notified of SocketNode events.
* @param l listener
*/
public void removeSocketNodeEventListener(
final SocketNodeEventListener l) {
listenerList.remove(l);
}
/**
Get the remote host to connect to for logging events.
@return host
*/
public String getHost() {
return host;
}
/**
* Configures the Host property, this will require activateOptions
* to be called for this to take effect.
* @param remoteHost address of remote host.
*/
public void setHost(final String remoteHost) {
this.host = remoteHost;
}
/**
Set the remote host to connect to for logging events.
Equivalent to setHost.
@param remoteHost address of remote host.
*/
public void setPort(final String remoteHost) {
host = remoteHost;
}
/**
Get the remote port to connect to for logging events.
@return port
*/
public int getPort() {
return port;
}
/**
Set the remote port to connect to for logging events.
@param p port
*/
public void setPort(final int p) {
this.port = p;
}
/**
The ReconnectionDelay option takes a positive integer
representing the number of milliseconds to wait between each
failed connection attempt to the server. The default value of
this option is 30000 which corresponds to 30 seconds.
Setting this option to zero turns off reconnection
capability.
@param delay milliseconds to wait or zero to not reconnect.
*/
public void setReconnectionDelay(final int delay) {
int oldValue = this.reconnectionDelay;
this.reconnectionDelay = delay;
firePropertyChange("reconnectionDelay", oldValue, this.reconnectionDelay);
}
/**
Returns value of the ReconnectionDelay option.
@return value of reconnection delay option.
*/
public int getReconnectionDelay() {
return reconnectionDelay;
}
/**
* Returns true if the receiver is the same class and they are
* configured for the same properties, and super class also considers
* them to be equivalent. This is used by PluginRegistry when determining
* if the a similarly configured receiver is being started.
*
* @param testPlugin The plugin to test equivalency against.
* @return boolean True if the testPlugin is equivalent to this plugin.
*/
public boolean isEquivalent(final Plugin testPlugin) {
if (testPlugin != null && testPlugin instanceof SocketHubReceiver) {
SocketHubReceiver sReceiver = (SocketHubReceiver) testPlugin;
return (port == sReceiver.getPort()
&& host.equals(sReceiver.getHost())
&& reconnectionDelay == sReceiver.getReconnectionDelay()
&& super.isEquivalent(testPlugin));
}
return false;
}
/**
Sets the flag to indicate if receiver is active or not.
@param b new value
*/
protected synchronized void setActive(final boolean b) {
active = b;
}
/**
Starts the SocketReceiver with the current options. */
public void activateOptions() {
if (!isActive()) {
setActive(true);
if (advertiseViaMulticastDNS) {
zeroConf = new ZeroConfSupport(ZONE, port, getName());
zeroConf.advertise();
}
fireConnector(false);
}
}
/**
Called when the receiver should be stopped. Closes the socket */
public synchronized void shutdown() {
// mark this as no longer running
active = false;
// close the socket
try {
if (socketNode != null) {
socketNode.close();
socketNode = null;
}
} catch (Exception e) {
getLogger().info("Excpetion closing socket", e);
// ignore for now
}
// stop the connector
if (connector != null) {
connector.interrupted = true;
connector = null; // allow gc
}
if (advertiseViaMulticastDNS) {
zeroConf.unadvertise();
}
}
/**
Listen for a socketClosedEvent from the SocketNode. Reopen the
socket if this receiver is still active.
@param e exception not used.
*/
public void socketClosedEvent(final Exception e) {
// if it is a non-normal closed event
// we clear the connector object here
// so that it actually does reconnect if the
// remote socket dies.
if (e != null) {
connector = null;
fireConnector(true);
}
}
/**
* Fire connectors.
* @param isReconnect true if reconnect.
*/
private synchronized void fireConnector(final boolean isReconnect) {
if (active && connector == null) {
getLogger().debug("Starting a new connector thread.");
connector = new Connector(isReconnect);
connector.setDaemon(true);
connector.setPriority(Thread.MIN_PRIORITY);
connector.start();
}
}
/**
* Set socket.
* @param newSocket new value for socket.
*/
private synchronized void setSocket(final Socket newSocket) {
connector = null;
socketNode = new SocketNode13(newSocket, this);
socketNode.addSocketNodeEventListener(this);
synchronized (listenerList) {
for (Iterator iter = listenerList.iterator(); iter.hasNext();) {
SocketNodeEventListener listener =
(SocketNodeEventListener) iter.next();
socketNode.addSocketNodeEventListener(listener);
}
}
new Thread(socketNode).start();
}
public void setAdvertiseViaMulticastDNS(boolean advertiseViaMulticastDNS) {
this.advertiseViaMulticastDNS = advertiseViaMulticastDNS;
}
public boolean isAdvertiseViaMulticastDNS() {
return advertiseViaMulticastDNS;
}
/**
The Connector will reconnect when the server becomes available
again. It does this by attempting to open a new connection every
It stops trying whenever a connection is established. It will
restart to try reconnect to the server when previpously open
connection is droppped.
@author Ceki Gülcü
*/
private final class Connector extends Thread {
/**
* Interruption status.
*/
boolean interrupted = false;
/**
* If true, then delay on next iteration.
*/
boolean doDelay;
/**
* Create new instance.
* @param isReconnect true if reconnecting.
*/
public Connector(final boolean isReconnect) {
super();
doDelay = isReconnect;
}
/**
* Attempt to connect until interrupted.
*/
public void run() {
while (!interrupted) {
try {
if (doDelay) {
getLogger().debug("waiting for " + reconnectionDelay
+ " milliseconds before reconnecting.");
sleep(reconnectionDelay);
}
doDelay = true;
getLogger().debug("Attempting connection to " + host);
Socket s = new Socket(host, port);
setSocket(s);
getLogger().debug(
"Connection established. Exiting connector thread.");
break;
} catch (InterruptedException e) {
getLogger().debug("Connector interrupted. Leaving loop.");
return;
} catch (java.net.ConnectException e) {
getLogger().debug("Remote host {} refused connection.", host);
} catch (IOException e) {
getLogger().debug("Could not connect to {}. Exception is {}.",
host, e);
}
}
}
}
/**
* This method does nothing.
* @param remoteInfo remote info.
*/
public void socketOpened(final String remoteInfo) {
// This method does nothing.
}
}
apache-log4j-extras1.2-1.2.17/src/main/java/org/apache/log4j/receivers/net/SocketNode13.java 0000664 0000000 0000000 00000021055 12527427642 0031110 0 ustar 00root root 0000000 0000000 /*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.log4j.receivers.net;
import org.apache.log4j.Logger;
import org.apache.log4j.component.helpers.Constants;
import org.apache.log4j.component.plugins.Pauseable;
import org.apache.log4j.component.plugins.Receiver;
import org.apache.log4j.component.spi.ComponentBase;
import org.apache.log4j.spi.LoggerRepository;
import org.apache.log4j.spi.LoggingEvent;
import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.net.Socket;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
// Contributors: Moses Hohman For example, the socket node might decide to log events to a
local file and also resent them to a second socket node.
Implementation lifted from org.apache.log4j.net.SocketNode
in log4j 1.3 and renamed to prevent collision with
log4j 1.2 implementation.
@author Ceki Gülcü
@author Paul Smith (psmith@apache.org)
*/
public class SocketNode13 extends ComponentBase implements Runnable, Pauseable {
/**
* Paused state.
*/
private boolean paused;
/**
* Closed state.
*/
private boolean closed;
/**
* Socket.
*/
private Socket socket;
/**
* Receiver.
*/
private Receiver receiver;
/**
* List of listeners.
*/
private List listenerList = Collections.synchronizedList(new ArrayList());
/**
Constructor for socket and logger repository.
@param s socket
@param hierarchy logger repository
*/
public SocketNode13(final Socket s,
final LoggerRepository hierarchy) {
super();
this.socket = s;
this.repository = hierarchy;
}
/**
Constructor for socket and receiver.
@param s socket
@param r receiver
*/
public SocketNode13(final Socket s, final Receiver r) {
super();
this.socket = s;
this.receiver = r;
}
/**
* Set the event listener on this node.
*
* @deprecated Now supports mutliple listeners, this method
* simply invokes the removeSocketNodeEventListener() to remove
* the listener, and then readds it.
* @param l listener
*/
public void setListener(final SocketNodeEventListener l) {
removeSocketNodeEventListener(l);
addSocketNodeEventListener(l);
}
/**
* Adds the listener to the list of listeners to be notified of the
* respective event.
* @param listener the listener to add to the list
*/
public void addSocketNodeEventListener(
final SocketNodeEventListener listener) {
listenerList.add(listener);
}
/**
* Removes the registered Listener from this instances list of
* listeners. If the listener has not been registered, then invoking
* this method has no effect.
*
* @param listener the SocketNodeEventListener to remove
*/
public void removeSocketNodeEventListener(
final SocketNodeEventListener listener) {
listenerList.remove(listener);
}
/**
* Deserialize events from socket until interrupted.
*/
public void run() {
LoggingEvent event;
Logger remoteLogger;
Exception listenerException = null;
ObjectInputStream ois = null;
try {
ois =
new ObjectInputStream(
new BufferedInputStream(socket.getInputStream()));
} catch (Exception e) {
ois = null;
listenerException = e;
getLogger().error("Exception opening ObjectInputStream to " + socket, e);
}
if (ois != null) {
String hostName = socket.getInetAddress().getHostName();
String remoteInfo = hostName + ":" + socket.getPort();
/**
* notify the listener that the socket has been
* opened and this SocketNode is ready and waiting
*/
fireSocketOpened(remoteInfo);
try {
while (!isClosed()) {
// read an event from the wire
event = (LoggingEvent) ois.readObject();
event.setProperty(Constants.HOSTNAME_KEY, hostName);
// store the known remote info in an event property
event.setProperty("log4j.remoteSourceInfo", remoteInfo);
// if configured with a receiver, tell it to post the event
if (!isPaused() && !isClosed()) {
if ((receiver != null)) {
receiver.doPost(event);
// else post it via the hierarchy
} else {
// get a logger from the hierarchy. The name of the logger
// is taken to be the name contained in the event.
remoteLogger = repository.getLogger(event.getLoggerName());
//event.logger = remoteLogger;
// apply the logger-level filter
if (event
.getLevel()
.isGreaterOrEqual(remoteLogger.getEffectiveLevel())) {
// finally log the event as if was generated locally
remoteLogger.callAppenders(event);
}
}
} else {
//we simply discard this event.
}
}
} catch (java.io.EOFException e) {
getLogger().info("Caught java.io.EOFException closing connection.");
listenerException = e;
} catch (java.net.SocketException e) {
getLogger().info("Caught java.net.SocketException closing connection.");
listenerException = e;
} catch (IOException e) {
getLogger().info("Caught java.io.IOException: " + e);
getLogger().info("Closing connection.");
listenerException = e;
} catch (Exception e) {
getLogger().error("Unexpected exception. Closing connection.", e);
listenerException = e;
}
}
// close the socket
try {
if (ois != null) {
ois.close();
}
} catch (Exception e) {
//getLogger().info("Could not close connection.", e);
}
// send event to listener, if configured
if (listenerList.size() > 0 && !isClosed()) {
fireSocketClosedEvent(listenerException);
}
}
/**
* Notifies all registered listeners regarding the closing of the Socket.
* @param listenerException listener exception
*/
private void fireSocketClosedEvent(final Exception listenerException) {
synchronized (listenerList) {
for (Iterator iter = listenerList.iterator(); iter.hasNext();) {
SocketNodeEventListener snel =
(SocketNodeEventListener) iter.next();
if (snel != null) {
snel.socketClosedEvent(listenerException);
}
}
}
}
/**
* Notifies all registered listeners regarding the opening of a Socket.
* @param remoteInfo remote info
*/
private void fireSocketOpened(final String remoteInfo) {
synchronized (listenerList) {
for (Iterator iter = listenerList.iterator(); iter.hasNext();) {
SocketNodeEventListener snel =
(SocketNodeEventListener) iter.next();
if (snel != null) {
snel.socketOpened(remoteInfo);
}
}
}
}
/**
* Sets if node is paused.
* @param b new value
*/
public void setPaused(final boolean b) {
this.paused = b;
}
/**
* Get if node is paused.
* @return true if pause.
*/
public boolean isPaused() {
return this.paused;
}
/**
* Close the node and underlying socket
*/
public void close() throws IOException {
getLogger().debug("closing socket");
this.closed = true;
socket.close();
fireSocketClosedEvent(null);
}
/**
* Get if node is closed.
* @return true if closed.
*/
public boolean isClosed() {
return this.closed;
}
}
SocketNodeEventListener.java 0000664 0000000 0000000 00000002750 12527427642 0033376 0 ustar 00root root 0000000 0000000 apache-log4j-extras1.2-1.2.17/src/main/java/org/apache/log4j/receivers/net /*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.log4j.receivers.net;
import java.util.EventListener;
/**
Interface used to listen for {@link org.apache.log4j.net.SocketNode} related
events. Clients register an instance of the interface and the
instance is called back when the various events occur.
@author Mark Womack
@author Paul Smith (psmith@apache.org)
*/
public interface SocketNodeEventListener extends EventListener {
/**
* Called when the SocketNode is created and begins awaiting data.
* @param remoteInfo remote info
*/
void socketOpened(String remoteInfo);
/**
Called when the socket the node was given has been closed.
@param e exception
*/
void socketClosedEvent(Exception e);
}
apache-log4j-extras1.2-1.2.17/src/main/java/org/apache/log4j/receivers/net/SocketReceiver.java 0000664 0000000 0000000 00000027701 12527427642 0031627 0 ustar 00root root 0000000 0000000 /*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.log4j.receivers.net;
import org.apache.log4j.component.plugins.Pauseable;
import org.apache.log4j.component.plugins.Plugin;
import org.apache.log4j.component.plugins.Receiver;
import org.apache.log4j.net.ZeroConfSupport;
import org.apache.log4j.spi.LoggerRepository;
import org.apache.log4j.spi.LoggingEvent;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.*;
/**
SocketReceiver receives a remote logging event on a configured
socket and "posts" it to a LoggerRepository as if the event was
generated locally. This class is designed to receive events from
the SocketAppender class (or classes that send compatible events).
Once the event has been "posted", it will be handled by the
appenders currently configured in the LoggerRespository.
@author Mark Womack
@author Scott Deboy (sdeboy@apache.org)
@author Paul Smith (psmith@apache.org)
*/
public class SocketReceiver extends Receiver implements Runnable, PortBased,
Pauseable {
/**
* socket map.
*/
private Map socketMap = new HashMap();
/**
* Paused.
*/
private boolean paused;
/**
* Thread.
*/
private Thread rThread;
/**
* Port.
*/
protected int port;
/**
* Server socket.
*/
private ServerSocket serverSocket;
/**
* Socket list.
*/
private Vector socketList = new Vector();
/**
* The MulticastDNS zone advertised by a SocketReceiver
*/
public static final String ZONE = "_log4j_obj_tcpaccept_receiver.local.";
/**
* Listener.
*/
private SocketNodeEventListener listener = null;
/**
* Listeners.
*/
private List listenerList = Collections.synchronizedList(new ArrayList());
private boolean advertiseViaMulticastDNS;
private ZeroConfSupport zeroConf;
/**
* Create new instance.
*/
public SocketReceiver() {
super();
}
/**
* Create new instance.
* @param p port
*/
public SocketReceiver(final int p) {
super();
port = p;
}
/**
* Create new instance.
* @param p port
* @param repo logger repository
*/
public SocketReceiver(final int p, final LoggerRepository repo) {
super();
this.port = p;
repository = repo;
}
public int getPort() {
return port;
}
public void setPort(final int p) {
port = p;
}
/**
* Returns true if the receiver is the same class and they are
* configured for the same properties, and super class also considers
* them to be equivalent. This is used by PluginRegistry when determining
* if the a similarly configured receiver is being started.
*
* @param testPlugin The plugin to test equivalency against.
* @return boolean True if the testPlugin is equivalent to this plugin.
*/
public boolean isEquivalent(final Plugin testPlugin) {
if ((testPlugin != null) && testPlugin instanceof SocketReceiver) {
SocketReceiver sReceiver = (SocketReceiver) testPlugin;
return (port == sReceiver.getPort() && super.isEquivalent(testPlugin));
}
return false;
}
/**
Starts the SocketReceiver with the current options. */
public void activateOptions() {
if (!isActive()) {
// shutdown();
rThread = new Thread(this);
rThread.setDaemon(true);
rThread.start();
if (advertiseViaMulticastDNS) {
zeroConf = new ZeroConfSupport(ZONE, port, getName());
zeroConf.advertise();
}
active = true;
}
}
/**
* Called when the receiver should be stopped. Closes the
* server socket and all of the open sockets.
*/
public synchronized void shutdown() {
getLogger().debug(getName() + " received shutdown request");
// mark this as no longer running
active = false;
if (rThread != null) {
rThread.interrupt();
rThread = null;
}
if (advertiseViaMulticastDNS) {
zeroConf.unadvertise();
}
doShutdown();
}
/**
* Does the actual shutting down by closing the server socket
* and any connected sockets that have been created.
*/
private synchronized void doShutdown() {
active = false;
getLogger().debug(getName() + " doShutdown called");
// close the server socket
closeServerSocket();
// close all of the accepted sockets
closeAllAcceptedSockets();
}
/**
* Closes the server socket, if created.
*/
private void closeServerSocket() {
getLogger().debug("{} closing server socket", getName());
try {
if (serverSocket != null) {
serverSocket.close();
}
} catch (Exception e) {
// ignore for now
}
serverSocket = null;
}
/**
* Closes all the connected sockets in the List.
*/
private synchronized void closeAllAcceptedSockets() {
for (int x = 0; x < socketList.size(); x++) {
try {
((Socket) socketList.get(x)).close();
} catch (Exception e) {
// ignore for now
}
}
// clear member variables
socketMap.clear();
socketList.clear();
}
/**
Sets the flag to indicate if receiver is active or not.
@param b new value
*/
protected synchronized void setActive(final boolean b) {
active = b;
}
public void setAdvertiseViaMulticastDNS(boolean advertiseViaMulticastDNS) {
this.advertiseViaMulticastDNS = advertiseViaMulticastDNS;
}
public boolean isAdvertiseViaMulticastDNS() {
return advertiseViaMulticastDNS;
}
/**
Loop, accepting new socket connections. */
public void run() {
/**
* Ensure we start fresh.
*/
closeServerSocket();
closeAllAcceptedSockets();
// start the server socket
try {
serverSocket = new ServerSocket(port);
} catch (Exception e) {
getLogger().error(
"error starting SocketReceiver (" + this.getName()
+ "), receiver did not start", e);
active = false;
return;
}
Socket socket = null;
try {
getLogger().debug("in run-about to enter while not interrupted loop");
active = true;
while (!rThread.isInterrupted()) {
// if we have a socket, start watching it
if (socket != null) {
getLogger().debug(
"socket not null - creating and starting socketnode");
socketList.add(socket);
SocketNode13 node = new SocketNode13(socket, this);
synchronized (listenerList) {
for (Iterator iter = listenerList.iterator();
iter.hasNext();) {
SocketNodeEventListener l =
(SocketNodeEventListener) iter.next();
node.addSocketNodeEventListener(l);
}
}
socketMap.put(socket, node);
new Thread(node).start();
socket = null;
}
getLogger().debug("waiting to accept socket");
// wait for a socket to open, then loop to start it
socket = serverSocket.accept();
getLogger().debug("accepted socket");
}
} catch (Exception e) {
getLogger().warn(
"exception while watching socket server in SocketReceiver ("
+ this.getName() + "), stopping");
}
getLogger().debug("{} has exited the not interrupted loop", getName());
// socket not watched because we a no longer running
// so close it now.
if (socket != null) {
try {
socket.close();
} catch (IOException e1) {
getLogger().warn("socket exception caught - socket closed");
}
}
getLogger().debug("{} is exiting main run loop", getName());
}
/**
* Returns a Vector of SocketDetail representing the IP/Domain name
* of the currently connected sockets that this receiver has
* been responsible for creating.
* @return Vector of SocketDetails
*/
public Vector getConnectedSocketDetails() {
Vector details = new Vector(socketList.size());
for (Enumeration enumeration = socketList.elements();
enumeration.hasMoreElements();
) {
Socket socket = (Socket) enumeration.nextElement();
details.add(
new SocketDetail(socket, (SocketNode13) socketMap.get(socket)));
}
return details;
}
/**
* Returns the currently configured SocketNodeEventListener that
* will be automatically set for each SocketNode created.
* @return SocketNodeEventListener currently configured
*
* @deprecated This receiver now supports multiple listeners
*/
public SocketNodeEventListener getListener() {
return listener;
}
/**
* Adds the listener to the list of listeners to be notified of the
* respective event.
* @param l the listener to add to the list
*/
public void addSocketNodeEventListener(
final SocketNodeEventListener l) {
listenerList.add(l);
}
/**
* Removes the registered Listener from this instances list of
* listeners. If the listener has not been registered, then invoking
* this method has no effect.
*
* @param l the SocketNodeEventListener to remove
*/
public void removeSocketNodeEventListener(
final SocketNodeEventListener l) {
listenerList.remove(l);
}
/**
* Sets the SocketNodeEventListener that will be used for each
* created SocketNode.
* @param l the listener to set on each creation of a SocketNode
* @deprecated This receiver now supports multiple listeners and
* so this method simply removes the listener (if there already)
* and readds it to the list.
*
* The passed listener will also be returned via the getListener()
* method still, but this is also deprecated
*/
public void setListener(final SocketNodeEventListener l) {
removeSocketNodeEventListener(l);
addSocketNodeEventListener(l);
this.listener = l;
}
/** {@inheritDoc} */
public boolean isPaused() {
return paused;
}
/** {@inheritDoc} */
public void setPaused(final boolean b) {
paused = b;
}
/**
* Socket detail.
*/
private static final class SocketDetail implements AddressBased, PortBased,
Pauseable {
/**
* Address.
*/
private String address;
/**
* Port.
*/
private int port;
/**
* Socket node.
*/
private SocketNode13 socketNode;
/**
* Create new instance.
* @param socket socket
* @param node socket node
*/
private SocketDetail(final Socket socket,
final SocketNode13 node) {
super();
this.address = socket.getInetAddress().getHostName();
this.port = socket.getPort();
this.socketNode = node;
}
/** {@inheritDoc} */
public String getAddress() {
return address;
}
/** {@inheritDoc} */
public int getPort() {
return port;
}
/** {@inheritDoc} */
public String getName() {
return "Socket";
}
/** {@inheritDoc} */
public boolean isActive() {
return true;
}
/** {@inheritDoc} */
public boolean isPaused() {
return socketNode.isPaused();
}
/** {@inheritDoc} */
public void setPaused(final boolean b) {
socketNode.setPaused(b);
}
}
/** {@inheritDoc} */
public void doPost(final LoggingEvent event) {
if (!isPaused()) {
super.doPost(event);
}
}
}
apache-log4j-extras1.2-1.2.17/src/main/java/org/apache/log4j/receivers/net/UDPAppender.java 0000664 0000000 0000000 00000021134 12527427642 0031013 0 ustar 00root root 0000000 0000000 /*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.log4j.receivers.net;
import org.apache.log4j.AppenderSkeleton;
import org.apache.log4j.component.helpers.Constants;
import org.apache.log4j.helpers.LogLog;
import org.apache.log4j.net.ZeroConfSupport;
import org.apache.log4j.spi.LoggingEvent;
import org.apache.log4j.xml.XMLLayout;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.UnknownHostException;
/**
* Sends log information as a UDP datagrams.
*
* The UDPAppender is meant to be used as a diagnostic logging tool
* so that logging can be monitored by a simple UDP client.
*
* Messages are not sent as LoggingEvent objects but as text after
* applying the designated Layout.
*
* The port and remoteHost properties can be set in configuration properties.
* By setting the remoteHost to a broadcast address any number of clients can
* listen for log messages.
*
* This was inspired and really extended/copied from {@link org.apache.log4j.net.SocketAppender}.
* Please see the docs for the proper credit to the authors of that class.
*
* @author Kevin Brown
* @author Scott Deboy This will mark the appender as closed and
call then {@link #cleanUp} method.
*/
public synchronized void close() {
if (closed) {
return;
}
if (advertiseViaMulticastDNS) {
zeroConf.unadvertise();
}
this.closed = true;
cleanUp();
}
/**
Close the UDP Socket and release the underlying
connector thread if it has been created
*/
public void cleanUp() {
if (outSocket != null) {
try {
outSocket.close();
} catch (Exception e) {
LogLog.error("Could not close outSocket.", e);
}
outSocket = null;
}
}
void connect(InetAddress address, int port) {
if (this.address == null) {
return;
}
try {
// First, close the previous connection if any.
cleanUp();
outSocket = new DatagramSocket();
outSocket.connect(address, port);
} catch (IOException e) {
LogLog.error(
"Could not open UDP Socket for sending.", e);
inError = true;
}
}
public void append(LoggingEvent event) {
if(inError) {
return;
}
if (event == null) {
return;
}
if (address == null) {
return;
}
if (outSocket != null) {
event.setProperty(Constants.HOSTNAME_KEY, hostname);
if (application != null) {
event.setProperty(Constants.APPLICATION_KEY, application);
}
try {
StringBuffer buf = new StringBuffer(layout.format(event));
byte[] payload;
if(encoding == null) {
payload = buf.toString().getBytes();
} else {
payload = buf.toString().getBytes(encoding);
}
DatagramPacket dp =
new DatagramPacket(payload, payload.length, address, port);
outSocket.send(dp);
} catch (IOException e) {
outSocket = null;
LogLog.warn("Detected problem with UDP connection: " + e);
}
}
}
public boolean isActive() {
return !inError;
}
InetAddress getAddressByName(String host) {
try {
return InetAddress.getByName(host);
} catch (Exception e) {
LogLog.error("Could not find address of [" + host + "].", e);
return null;
}
}
/**
The UDPAppender uses layouts. Hence, this method returns
For example, the socket node might decide to log events to a
local file and also resent them to a second socket node.
@author Scott Deboy
This receiver supports log files created using log4j's XMLLayout, as well as java.util.logging
XMLFormatter (via the org.apache.log4j.spi.Decoder interface).
By default, log4j's XMLLayout is supported (no need to specify a decoder in that case).
To configure this receiver to support java.util.logging's XMLFormatter, specify a 'decoder' param
of org.apache.log4j.xml.UtilLoggingXMLDecoder.
Once the event has been "posted", it will be handled by the
appenders currently configured in the LoggerRespository.
@author Mark Womack
@author Scott Deboy
apache-log4j-extras1.2-1.2.17/src/main/java/org/apache/log4j/receivers/ 0000775 0000000 0000000 00000000000 12527427642 0025252 5 ustar 00root root 0000000 0000000 apache-log4j-extras1.2-1.2.17/src/main/java/org/apache/log4j/receivers/db/ 0000775 0000000 0000000 00000000000 12527427642 0025637 5 ustar 00root root 0000000 0000000 apache-log4j-extras1.2-1.2.17/src/main/java/org/apache/log4j/receivers/db/ConnectionSource.java 0000664 0000000 0000000 00000004573 12527427642 0031773 0 ustar 00root root 0000000 0000000 /*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.log4j.receivers.db;
import org.apache.log4j.component.spi.Component;
import org.apache.log4j.spi.OptionHandler;
import java.sql.Connection;
import java.sql.SQLException;
/**
* The null
if not overridden.
*/
public String getOverriddenSupportsGetGeneratedKeys() {
return overriddenSupportsGetGeneratedKeys != null ? overriddenSupportsGetGeneratedKeys
.toString()
: null;
}
/**
* Sets the "overridden" value of "supportsGetGeneratedKeys" property of the
* JDBC driver. In certain cases, getting (e.g. Oracle 10g) generated keys
* does not work because it returns the ROWID, not the value of the sequence.
*
* @param overriddenSupportsGetGeneratedKeys
* A non null string, with "true" or "false" value, if overridden,
* null
if not overridden.
*/
public void setOverriddenSupportsGetGeneratedKeys(
String overriddenSupportsGetGeneratedKeys) {
this.overriddenSupportsGetGeneratedKeys = Boolean
.valueOf(overriddenSupportsGetGeneratedKeys);
}
/**
* Does this connection support batch updates?
*/
public final boolean supportsBatchUpdates() {
return supportsBatchUpdates;
}
}
apache-log4j-extras1.2-1.2.17/src/main/java/org/apache/log4j/receivers/db/CustomSQLDBReceiver.java 0000664 0000000 0000000 00000041546 12527427642 0032241 0 ustar 00root root 0000000 0000000 /*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.log4j.receivers.db;
import org.apache.log4j.Level;
import org.apache.log4j.Logger;
import org.apache.log4j.component.plugins.Pauseable;
import org.apache.log4j.component.plugins.Receiver;
import org.apache.log4j.component.scheduler.Job;
import org.apache.log4j.component.scheduler.Scheduler;
import org.apache.log4j.component.spi.LoggerRepositoryEx;
import org.apache.log4j.spi.LocationInfo;
import org.apache.log4j.spi.LoggingEvent;
import org.apache.log4j.spi.ThrowableInformation;
import org.apache.log4j.xml.DOMConfigurator;
import org.apache.log4j.xml.UnrecognizedElementHandler;
import org.w3c.dom.Element;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Hashtable;
import java.util.Properties;
import java.util.StringTokenizer;
/**
* Converts log data stored in a database into LoggingEvents.
*
*
* <connectionSource class="org.apache.log4j.jdbc.DriverManagerConnectionSource">
* <param name="driver" value="com.mysql.jdbc.Driver" />
* <param name="url" value="jdbc:mysql://localhost:3306/mydb" />
* <param name="username" value="myUser" />
* <param name="password" value="myPassword" />
* </connectionSource>
*
*
*
* <connectionSource class="org.apache.log4j.jdbc.DriverManagerConnectionSource">
* <param name="driver" value="org.apache.commons.dbcp.PoolingDriver" />
* <param name="url" value="jdbc:apache:commons:dbcp:/myPoolingDriver" />
* </connectionSource>
*
* Then the configuration information for the commons-dbcp package goes into
* the file myPoolingDriver.jocl and is placed in the classpath. See the
* commons-dbcp
* documentation for details.
*
* @author Ray DeCampo
*/
public class DriverManagerConnectionSource extends ConnectionSourceSkeleton {
private String driverClass = null;
private String url = null;
public void activateOptions() {
try {
if (driverClass != null) {
Class.forName(driverClass);
discoverConnnectionProperties();
} else {
getLogger().error(
"WARNING: No JDBC driver specified for log4j DriverManagerConnectionSource.");
}
} catch (final ClassNotFoundException cnfe) {
getLogger().error("Could not load JDBC driver class: " + driverClass, cnfe);
}
}
/**
* @see org.apache.log4j.receivers.db.ConnectionSource#getConnection()
*/
public Connection getConnection() throws SQLException {
if (getUser() == null) {
return DriverManager.getConnection(url);
} else {
return DriverManager.getConnection(url, getUser(), getPassword());
}
}
/**
* Returns the url.
* @return String
*/
public String getUrl() {
return url;
}
/**
* Sets the url.
* @param url The url to set
*/
public void setUrl(String url) {
this.url = url;
}
/**
* Returns the name of the driver class.
* @return String
*/
public String getDriverClass() {
return driverClass;
}
/**
* Sets the driver class.
* @param driverClass The driver class to set
*/
public void setDriverClass(String driverClass) {
this.driverClass = driverClass;
}
}
apache-log4j-extras1.2-1.2.17/src/main/java/org/apache/log4j/receivers/db/JNDIConnectionSource.java 0000664 0000000 0000000 00000011451 12527427642 0032431 0 ustar 00root root 0000000 0000000 /*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.log4j.receivers.db;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.SQLException;
// PortableRemoteObject was introduced in JDK 1.3. We won't use it.
// import javax.rmi.PortableRemoteObject;
/**
* The
*
* <connectionSource class="org.apache.log4j.jdbc.JNDIConnectionSource">
* <param name="jndiLocation" value="jdbc/MySQLDS" />
* </connectionSource>
*
*
*
* <connectionSource class="org.apache.log4j.jdbc.JNDIConnectionSource">
* <param name="jndiLocation" value="jdbc/MySQLDS" />
* <param name="username" value="myUser" />
* <param name="password" value="myPassword" />
* </connectionSource>
*
* reconnectionDelay
milliseconds.
address
and port
.
*/
public UDPAppender(final InetAddress address, final int port) {
super(false);
this.address = address;
this.remoteHost = address.getHostName();
this.port = port;
activateOptions();
}
/**
Sends UDP packets to the address
and port
.
*/
public UDPAppender(final String host, final int port) {
super(false);
this.port = port;
this.address = getAddressByName(host);
this.remoteHost = host;
activateOptions();
}
/**
Open the UDP sender for the RemoteHost and Port.
*/
public void activateOptions() {
try {
hostname = InetAddress.getLocalHost().getHostName();
} catch (UnknownHostException uhe) {
try {
hostname = InetAddress.getLocalHost().getHostAddress();
} catch (UnknownHostException uhe2) {
hostname = "unknown";
}
}
//allow system property of application to be primary
if (application == null) {
application = System.getProperty(Constants.APPLICATION_KEY);
} else {
if (System.getProperty(Constants.APPLICATION_KEY) != null) {
application = application + "-" + System.getProperty(Constants.APPLICATION_KEY);
}
}
if(remoteHost != null) {
address = getAddressByName(remoteHost);
connect(address, port);
} else {
String err = "The RemoteHost property is required for SocketAppender named "+ name;
LogLog.error(err);
throw new IllegalStateException(err);
}
if (layout == null) {
layout = new XMLLayout();
}
if (advertiseViaMulticastDNS) {
zeroConf = new ZeroConfSupport(ZONE, port, getName());
zeroConf.advertise();
}
super.activateOptions();
}
/**
Close this appender.
true
.
*/
public boolean requiresLayout() {
return true;
}
/**
The RemoteHost option takes a string value which should be
the host name or ipaddress to send the UDP packets.
*/
public void setRemoteHost(String host) {
remoteHost = host;
}
/**
Returns value of the RemoteHost option.
*/
public String getRemoteHost() {
return remoteHost;
}
/**
The App option takes a string value which should be the name of the application getting logged.
If property was already set (via system property), don't set here.
*/
public void setApplication(String app) {
this.application = app;
}
/**
Returns value of the App option.
*/
public String getApplication() {
return application;
}
/**
The Encoding option specifies how the bytes are encoded. If this option is not specified,
the System encoding is used.
*/
public void setEncoding(String encoding) {
this.encoding = encoding;
}
/**
Returns value of the Encoding option.
*/
public String getEncoding() {
return encoding;
}
/**
The Port option takes a positive integer representing
the port where UDP packets will be sent.
*/
public void setPort(int port) {
this.port = port;
}
/**
Returns value of the Port option.
*/
public int getPort() {
return port;
}
public void setAdvertiseViaMulticastDNS(boolean advertiseViaMulticastDNS) {
this.advertiseViaMulticastDNS = advertiseViaMulticastDNS;
}
public boolean isAdvertiseViaMulticastDNS() {
return advertiseViaMulticastDNS;
}
}
apache-log4j-extras1.2-1.2.17/src/main/java/org/apache/log4j/receivers/net/UDPReceiver.java 0000664 0000000 0000000 00000016457 12527427642 0031035 0 ustar 00root root 0000000 0000000 /*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.log4j.receivers.net;
import org.apache.log4j.component.plugins.Pauseable;
import org.apache.log4j.component.plugins.Receiver;
import org.apache.log4j.net.ZeroConfSupport;
import org.apache.log4j.receivers.spi.Decoder;
import org.apache.log4j.spi.LoggingEvent;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
/**
* Receive LoggingEvents encoded with an XMLLayout, convert the XML data to a
* LoggingEvent and post the LoggingEvent.
*
* @author Scott Deboy