| /* |
| * 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. |
| */ |
| |
| #ifndef _LOG4CXX_DB_ODBC_APPENDER_H |
| #define _LOG4CXX_DB_ODBC_APPENDER_H |
| |
| #if defined(_MSC_VER) |
| #pragma warning ( push ) |
| #pragma warning ( disable: 4231 4251 4275 4786 ) |
| #endif |
| |
| |
| #include <log4cxx/log4cxx.h> |
| |
| #include <log4cxx/helpers/exception.h> |
| #include <log4cxx/appenderskeleton.h> |
| #include <log4cxx/spi/loggingevent.h> |
| #include <list> |
| |
| namespace log4cxx |
| { |
| namespace db |
| { |
| class LOG4CXX_EXPORT SQLException : public log4cxx::helpers::Exception { |
| public: |
| SQLException(short fHandleType, |
| void* hInput, const char* prolog, |
| log4cxx::helpers::Pool& p); |
| SQLException(const char* msg); |
| SQLException(const SQLException& src); |
| private: |
| const char* formatMessage(short fHandleType, |
| void* hInput, const char* prolog, |
| log4cxx::helpers::Pool& p); |
| }; |
| |
| /** |
| <p><b>WARNING: This version of ODBCAppender |
| is very likely to be completely replaced in the future. Moreoever, |
| it does not log exceptions.</b> </p> |
| |
| The ODBCAppender provides for sending log events to a database. |
| |
| |
| <p>Each append call adds to an <code>ArrayList</code> buffer. When |
| the buffer is filled each log event is placed in a sql statement |
| (configurable) and executed. |
| |
| <b>BufferSize</b>, <b>db URL</b>, <b>User</b>, & <b>Password</b> are |
| configurable options in the standard log4j ways. |
| |
| <p>The <code>setSql(String sql)</code> sets the SQL statement to be |
| used for logging -- this statement is sent to a |
| <code>PatternLayout</code> (either created automaticly by the |
| appender or added by the user). Therefore by default all the |
| conversion patterns in <code>PatternLayout</code> can be used |
| inside of the statement. (see the test cases for examples) |
| |
| <p>Overriding the {@link #getLogStatement} method allows more |
| explicit control of the statement used for logging. |
| |
| <p>For use as a base class: |
| |
| <ul> |
| |
| <li>Override getConnection() to pass any connection |
| you want. Typically this is used to enable application wide |
| connection pooling. |
| |
| <li>Override closeConnection -- if |
| you override getConnection make sure to implement |
| <code>closeConnection</code> to handle the connection you |
| generated. Typically this would return the connection to the |
| pool it came from. |
| |
| <li>Override getLogStatement to |
| produce specialized or dynamic statements. The default uses the |
| sql option value. |
| |
| </ul> |
| */ |
| |
| class LOG4CXX_EXPORT ODBCAppender : public AppenderSkeleton |
| { |
| protected: |
| /** |
| * URL of the DB for default connection handling |
| */ |
| LogString databaseURL; |
| |
| /** |
| * User to connect as for default connection handling |
| */ |
| LogString databaseUser; |
| |
| /** |
| * User to use for default connection handling |
| */ |
| LogString databasePassword; |
| |
| typedef void* SQLHDBC; |
| typedef void* SQLHENV; |
| typedef void* SQLHANDLE; |
| typedef short SQLSMALLINT; |
| |
| /** |
| * Connection used by default. The connection is opened the first time it |
| * is needed and then held open until the appender is closed (usually at |
| * garbage collection). This behavior is best modified by creating a |
| * sub-class and overriding the <code>getConnection</code> and |
| * <code>closeConnection</code> methods. |
| */ |
| SQLHDBC connection; |
| SQLHENV env; |
| |
| /** |
| * Stores the string given to the pattern layout for conversion into a SQL |
| * statement, eg: insert into LogTable (Thread, File, Message) values |
| * ("%t", "%F", "%m") |
| * |
| * Be careful of quotes in your messages! |
| * |
| * Also see PatternLayout. |
| */ |
| LogString sqlStatement; |
| |
| /** |
| * size of LoggingEvent buffer before writing to the database. |
| * Default is 1. |
| */ |
| size_t bufferSize; |
| |
| /** |
| * ArrayList holding the buffer of Logging Events. |
| */ |
| std::list<spi::LoggingEventPtr> buffer; |
| |
| public: |
| DECLARE_LOG4CXX_OBJECT(ODBCAppender) |
| BEGIN_LOG4CXX_CAST_MAP() |
| LOG4CXX_CAST_ENTRY(ODBCAppender) |
| LOG4CXX_CAST_ENTRY_CHAIN(AppenderSkeleton) |
| END_LOG4CXX_CAST_MAP() |
| |
| ODBCAppender(); |
| virtual ~ODBCAppender(); |
| |
| /** |
| Set options |
| */ |
| virtual void setOption(const LogString& option, const LogString& value); |
| |
| /** |
| Activate the specified options. |
| */ |
| virtual void activateOptions(log4cxx::helpers::Pool& p); |
| |
| /** |
| * Adds the event to the buffer. When full the buffer is flushed. |
| */ |
| void append(const spi::LoggingEventPtr& event, log4cxx::helpers::Pool&); |
| |
| /** |
| * By default getLogStatement sends the event to the required Layout object. |
| * The layout will format the given pattern into a workable SQL string. |
| * |
| * Overriding this provides direct access to the LoggingEvent |
| * when constructing the logging statement. |
| * |
| */ |
| protected: |
| LogString getLogStatement(const spi::LoggingEventPtr& event, |
| helpers::Pool& p) const; |
| |
| /** |
| * |
| * Override this to provide an alertnate method of getting |
| * connections (such as caching). One method to fix this is to open |
| * connections at the start of flushBuffer() and close them at the |
| * end. I use a connection pool outside of ODBCAppender which is |
| * accessed in an override of this method. |
| * */ |
| virtual void execute(const LogString& sql, |
| log4cxx::helpers::Pool& p) /*throw(SQLException)*/; |
| |
| /** |
| * Override this to return the connection to a pool, or to clean up the |
| * resource. |
| * |
| * The default behavior holds a single connection open until the appender |
| * is closed (typically when garbage collected). |
| */ |
| virtual void closeConnection(SQLHDBC con); |
| |
| /** |
| * Override this to link with your connection pooling system. |
| * |
| * By default this creates a single connection which is held open |
| * until the object is garbage collected. |
| */ |
| virtual SQLHDBC getConnection(log4cxx::helpers::Pool& p) /*throw(SQLException)*/; |
| |
| /** |
| * Closes the appender, flushing the buffer first then closing the default |
| * connection if it is open. |
| */ |
| public: |
| virtual void close(); |
| |
| /** |
| * loops through the buffer of LoggingEvents, gets a |
| * sql string from getLogStatement() and sends it to execute(). |
| * Errors are sent to the errorHandler. |
| * |
| * If a statement fails the LoggingEvent stays in the buffer! |
| */ |
| virtual void flushBuffer(log4cxx::helpers::Pool& p); |
| |
| /** |
| * ODBCAppender requires a layout. |
| * */ |
| virtual bool requiresLayout() const |
| { return true; } |
| |
| /** |
| * Set pre-formated statement eg: insert into LogTable (msg) values ("%m") |
| */ |
| void setSql(const LogString& s); |
| |
| /** |
| * Returns pre-formated statement eg: insert into LogTable (msg) values ("%m") |
| */ |
| inline const LogString& getSql() const |
| { return sqlStatement; } |
| |
| |
| inline void setUser(const LogString& user) |
| { databaseUser = user; } |
| |
| |
| inline void setURL(const LogString& url) |
| { databaseURL = url; } |
| |
| |
| inline void setPassword(const LogString& password) |
| { databasePassword = password; } |
| |
| |
| inline void setBufferSize(size_t newBufferSize) |
| { bufferSize = newBufferSize; } |
| |
| inline const LogString& getUser() const |
| { return databaseUser; } |
| |
| |
| inline const LogString& getURL() const |
| { return databaseURL; } |
| |
| |
| inline const LogString& getPassword() const |
| { return databasePassword; } |
| |
| inline size_t getBufferSize() const |
| { return bufferSize; } |
| private: |
| ODBCAppender(const ODBCAppender&); |
| ODBCAppender& operator=(const ODBCAppender&); |
| static void encode(wchar_t** dest, const LogString& src, |
| log4cxx::helpers::Pool& p); |
| static void encode(unsigned short** dest, const LogString& src, |
| log4cxx::helpers::Pool& p); |
| }; // class ODBCAppender |
| LOG4CXX_PTR_DEF(ODBCAppender); |
| |
| } // namespace db |
| } // namespace log4cxx |
| |
| #if defined(_MSC_VER) |
| #pragma warning ( pop ) |
| #endif |
| |
| #endif // _LOG4CXX_DB_ODBC_APPENDER_H |