This is an automated email from the ASF dual-hosted git repository.
rmiddleton pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/logging-log4cxx.git
The following commit(s) were added to refs/heads/master by this push:
new fc1c3c64 Column mappings are required to insert messages (#213)
fc1c3c64 is described below
commit fc1c3c64678b69be336eab7a84a3ae8e2bedce1a
Author: Robert Middleton <[email protected]>
AuthorDate: Wed May 3 06:27:35 2023 -0400
Column mappings are required to insert messages (#213)
* Column mappings are required to insert messages
* Remove references to PatterLayout supported queries from documentation.
Remove unused code.
---------
Co-authored-by: Stephen Webb <[email protected]>
---
src/main/cpp/odbcappender.cpp | 81 +++++-----------------
src/main/include/log4cxx/db/odbcappender.h | 24 +------
.../input/xml/odbcAppenderDSN-Log4cxxTest.xml | 9 +--
3 files changed, 21 insertions(+), 93 deletions(-)
diff --git a/src/main/cpp/odbcappender.cpp b/src/main/cpp/odbcappender.cpp
index f6f93158..2e757b0d 100644
--- a/src/main/cpp/odbcappender.cpp
+++ b/src/main/cpp/odbcappender.cpp
@@ -192,7 +192,7 @@ void ODBCAppender::setOption(const LogString& option, const
LogString& value)
bool ODBCAppender::requiresLayout() const
{
- return false;
+ return false;
}
void ODBCAppender::activateOptions(log4cxx::helpers::Pool&)
@@ -200,6 +200,10 @@ void ODBCAppender::activateOptions(log4cxx::helpers::Pool&)
#if !LOG4CXX_HAVE_ODBC
LogLog::error(LOG4CXX_STR("Can not activate ODBCAppender unless
compiled with ODBC support."));
#else
+ if (_priv->mappedName.empty())
+ {
+ LogLog::error(LOG4CXX_STR("ODBCAppender column mappings not
defined, logging events will not be inserted"));
+ }
auto specs = getFormatSpecifiers();
for (auto& name : _priv->mappedName)
{
@@ -248,56 +252,11 @@ void ODBCAppender::append(const spi::LoggingEventPtr&
event, log4cxx::helpers::P
LogString ODBCAppender::getLogStatement(const spi::LoggingEventPtr& event,
log4cxx::helpers::Pool& p) const
{
- return event->getMessage();
+ return LogString();
}
void ODBCAppender::execute(const LogString& sql, log4cxx::helpers::Pool& p)
{
-#if LOG4CXX_HAVE_ODBC
- SQLRETURN ret;
- SQLHDBC con = SQL_NULL_HDBC;
- SQLHSTMT stmt = SQL_NULL_HSTMT;
-
- try
- {
- con = getConnection(p);
-
- ret = SQLAllocHandle( SQL_HANDLE_STMT, con, &stmt);
-
- if (ret < 0)
- {
- throw SQLException( SQL_HANDLE_DBC, con, "Failed to
allocate sql handle", p);
- }
-
-#if LOG4CXX_LOGCHAR_IS_WCHAR
- ret = SQLExecDirectW(stmt, (SQLWCHAR*)sql.c_str(), SQL_NTS);
-#elif LOG4CXX_LOGCHAR_IS_UTF8
- ret = SQLExecDirectA(stmt, (SQLCHAR*)sql.c_str(), SQL_NTS);
-#else
- SQLWCHAR* wsql;
- encode(&wsql, sql, p);
- ret = SQLExecDirectW(stmt, wsql, SQL_NTS);
-#endif
- if (ret < 0)
- {
- throw SQLException(SQL_HANDLE_STMT, stmt, "Failed to
execute sql statement", p);
- }
- }
- catch (SQLException&)
- {
- if (stmt != SQL_NULL_HSTMT)
- {
- SQLFreeHandle(SQL_HANDLE_STMT, stmt);
- }
-
- throw;
- }
-
- SQLFreeHandle(SQL_HANDLE_STMT, stmt);
- closeConnection(con);
-#else
- throw SQLException("log4cxx build without ODBC support");
-#endif
}
/* The default behavior holds a single connection open until the appender
@@ -609,25 +568,18 @@ void ODBCAppender::flushBuffer(Pool& p)
{
for (auto& logEvent : _priv->buffer)
{
- try
- {
- if (!_priv->parameterValue.empty())
- {
+ if (_priv->parameterValue.empty())
+ _priv->errorHandler->error(LOG4CXX_STR("ODBCAppender
column mappings not defined"));
#if LOG4CXX_HAVE_ODBC
- if (0 == _priv->preparedStatement)
-
_priv->setPreparedStatement(getConnection(p), p);
- _priv->setParameterValues(logEvent, p);
- auto ret = SQLExecute(_priv->preparedStatement);
- if (ret < 0)
- {
- throw SQLException(SQL_HANDLE_STMT,
_priv->preparedStatement, "Failed to execute prepared statement", p);
- }
-#endif
- }
- else
+ else try
+ {
+ if (0 == _priv->preparedStatement)
+ _priv->setPreparedStatement(getConnection(p),
p);
+ _priv->setParameterValues(logEvent, p);
+ auto ret = SQLExecute(_priv->preparedStatement);
+ if (ret < 0)
{
- auto sql = getLogStatement(logEvent, p);
- execute(sql, p);
+ throw SQLException(SQL_HANDLE_STMT,
_priv->preparedStatement, "Failed to execute prepared statement", p);
}
}
catch (SQLException& e)
@@ -635,6 +587,7 @@ void ODBCAppender::flushBuffer(Pool& p)
_priv->errorHandler->error(LOG4CXX_STR("Failed to
execute sql"), e,
ErrorCode::FLUSH_FAILURE);
}
+#endif
}
// clear the buffer of reported events
diff --git a/src/main/include/log4cxx/db/odbcappender.h
b/src/main/include/log4cxx/db/odbcappender.h
index 6c65ad45..3b308add 100644
--- a/src/main/include/log4cxx/db/odbcappender.h
+++ b/src/main/include/log4cxx/db/odbcappender.h
@@ -56,16 +56,6 @@ either in the Log4cxx configuration file
using the <b>sql</b> parameter element
or programatically by calling the <code>setSql(String sql)</code> method.
-If no <b>ColumnMapping</b> element is provided in the configuration file
-the sql statement is assumed to be a PatternLayout layout.
-In this case all the conversion patterns in PatternLayout
-can be used inside of the statement. (see the test cases for examples)
-
-If the <b>sql</b> element is not provided
-and no <b>ColumnMapping</b> element is provided
-the attached a PatternLayout layout element
-is assumed to contain the sql statement.
-
The following <b>param</b> elements are optional:
- one of <b>DSN</b>, <b>URL</b>, <b>ConnectionString</b> -
The <b>serverName</b> parameter value in the <a
href="https://learn.microsoft.com/en-us/sql/odbc/reference/syntax/sqlconnect-function">SQLConnect</a>
call.
@@ -138,10 +128,6 @@ An example configuration that writes to the data source
named "LoggingDSN" is:
<priority value ="INFO" />
<appender-ref ref="ASYNC" />
</root>
-<appender name="PatternAppender" class="ODBCAppender">
- <param name="DSN" value="LoggingDSN"/>
- <param name="sql" value="INSERT INTO [ApplicationLogs].[dbo].[UnitTestLog]
([Thread],[LogName],[LogTime],[LogLevel],[FileName],[FileLine],[Message],[MappedContext])
VALUES ('%t', '%c','%d{yyyy-MM-dd
HH:mm:ss.SSSSSS}','%p','%f','%L','%m{'}','%J{'}')" />
-</appender>
</log4j:configuration>
~~~
@@ -182,20 +168,14 @@ class LOG4CXX_EXPORT ODBCAppender : public
AppenderSkeleton
protected:
/**
- * Sends the event to the attached PatternLayout object.
- * The layout will format the given pattern into a workable SQL
string.
- *
+ * To be removed.
*/
LogString getLogStatement(const spi::LoggingEventPtr& event,
helpers::Pool& p) const;
/**
*
- * Override this to provide an alternate 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.
+ * To be removed.
* */
virtual void execute(const LogString& sql,
log4cxx::helpers::Pool& p) /*throw(SQLException)*/;
diff --git a/src/test/resources/input/xml/odbcAppenderDSN-Log4cxxTest.xml
b/src/test/resources/input/xml/odbcAppenderDSN-Log4cxxTest.xml
index c82c63ba..04e278da 100644
--- a/src/test/resources/input/xml/odbcAppenderDSN-Log4cxxTest.xml
+++ b/src/test/resources/input/xml/odbcAppenderDSN-Log4cxxTest.xml
@@ -25,15 +25,10 @@
<param name="ConversionPattern" value="%d %-5p %c{2} - %m%n"/>
</layout>
</appender>
-<appender name="PatternAppender" class="ODBCAppender">
- <param name="DSN" value="Log4cxxTest"/>
- <param name="sql" value="INSERT INTO UnitTestLog
(Thread,LogName,LogTime,LogLevel,FileName,FileLine,Message) VALUES
('%t','%c','%d{yyyy-MM-dd HH:mm:ss.SSSSSS}','%p','%f','%L','%m{'}')" />
- <!--param name="sql" value="INSERT INTO ApplicationLogs.dbo.UnitTestLog
(Thread,LogName,LogTime,LogLevel,FileName,FileLine,Message) VALUES
('%t','%c','%d{yyyy-MM-dd HH:mm:ss.SSSSSS}','%p','%f','%L','%m{'}')" /-->
-</appender>
<appender name="PreparedAppender" class="ODBCAppender">
<param name="DSN" value="Log4cxxTest"/>
- <param name="sql" value="INSERT INTO UnitTestLog
(Thread,LogName,LogTime,LogLevel,FileName,FileLine,Message) VALUES
(?,?,?,?,?,?,?)" />
- <!--param name="sql" value="INSERT INTO ApplicationLogs.dbo.UnitTestLog
(Thread,LogName,LogTime,LogLevel,FileName,FileLine,Message) VALUES
(?,?,?,?,?,?,?)" /-->
+ <!--param name="sql" value="INSERT INTO UnitTestLog
(Thread,LogName,LogTime,LogLevel,FileName,FileLine,Message) VALUES
(?,?,?,?,?,?,?)" /-->
+ <param name="sql" value="INSERT INTO ApplicationLogs.dbo.UnitTestLog
(Thread,LogName,LogTime,LogLevel,FileName,FileLine,Message) VALUES
(?,?,?,?,?,?,?)" />
<param name="ColumnMapping" value="thread"/>
<param name="ColumnMapping" value="logger"/>
<param name="ColumnMapping" value="time"/>