You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@logging.apache.org by sw...@apache.org on 2023/04/25 05:32:25 UTC
[logging-log4cxx] 01/01: ODBCAppender support for logging a single value or all values (as JASON) of an event's mapped diagnostic context
This is an automated email from the ASF dual-hosted git repository.
swebb2066 pushed a commit to branch mdc_pattern_converter
in repository https://gitbox.apache.org/repos/asf/logging-log4cxx.git
commit 875a0f655844bbe549303f0e1dccaefb5190a8d2
Author: Stephen Webb <sw...@gmail.com>
AuthorDate: Tue Apr 25 15:32:05 2023 +1000
ODBCAppender support for logging a single value or all values (as JASON) of an event's mapped diagnostic context
---
src/main/cpp/CMakeLists.txt | 1 +
src/main/cpp/jsonlayout.cpp | 2 +-
src/main/cpp/mdcpatternconverter.cpp | 61 ++++++++++++++++++++++
src/main/cpp/odbcappender.cpp | 25 ++++++++-
src/main/include/log4cxx/db/odbcappender.h | 26 ++++-----
src/main/include/log4cxx/jsonlayout.h | 2 +-
.../include/log4cxx/pattern/mdcpatternconverter.h | 57 ++++++++++++++++++++
7 files changed, 158 insertions(+), 16 deletions(-)
diff --git a/src/main/cpp/CMakeLists.txt b/src/main/cpp/CMakeLists.txt
index fcf25b88..55c10381 100644
--- a/src/main/cpp/CMakeLists.txt
+++ b/src/main/cpp/CMakeLists.txt
@@ -143,6 +143,7 @@ target_sources(log4cxx
nameabbreviator.cpp
namepatternconverter.cpp
ndc.cpp
+ mdcpatternconverter.cpp
ndcpatternconverter.cpp
nteventlogappender.cpp
odbcappender.cpp
diff --git a/src/main/cpp/jsonlayout.cpp b/src/main/cpp/jsonlayout.cpp
index aca87f51..6e8a7ce7 100644
--- a/src/main/cpp/jsonlayout.cpp
+++ b/src/main/cpp/jsonlayout.cpp
@@ -171,7 +171,7 @@ void JSONLayout::format(LogString& output,
}
void JSONLayout::appendQuotedEscapedString(LogString& buf,
- const LogString& input) const
+ const LogString& input)
{
/* add leading quote */
buf.push_back(0x22);
diff --git a/src/main/cpp/mdcpatternconverter.cpp b/src/main/cpp/mdcpatternconverter.cpp
new file mode 100644
index 00000000..9b4ac2ef
--- /dev/null
+++ b/src/main/cpp/mdcpatternconverter.cpp
@@ -0,0 +1,61 @@
+/*
+ * 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.
+ */
+
+#include <log4cxx/pattern/mdcpatternconverter.h>
+#include <log4cxx/private/patternconverter_priv.h>
+#include <log4cxx/spi/loggingevent.h>
+#include <log4cxx/jsonlayout.h>
+
+using namespace log4cxx;
+using namespace log4cxx::pattern;
+
+IMPLEMENT_LOG4CXX_OBJECT(MDCPatternConverter)
+
+MDCPatternConverter::MDCPatternConverter
+ ( const LogString& name
+ , const LogString& style
+ , const std::vector<LogString>& options
+ )
+ : LoggingEventPatternConverter(std::make_unique<PatternConverter::PatternConverterPrivate>(name, style))
+{
+}
+
+void MDCPatternConverter::format
+ ( const spi::LoggingEventPtr& event
+ , LogString& toAppendTo
+ , helpers::Pool& /* p */
+ ) const
+{
+ if (m_priv->name.empty())
+ {
+ bool first = true;
+ for (auto key : event->getMDCKeySet())
+ {
+ toAppendTo.append(first ? LOG4CXX_STR("{") : LOG4CXX_STR(","));
+ JSONLayout::appendQuotedEscapedString(toAppendTo, key);
+ toAppendTo.append(LOG4CXX_STR(":"));
+ LogString value;
+ event->getMDC(key, value);
+ JSONLayout::appendQuotedEscapedString(toAppendTo, value);
+ first = false;
+ }
+ if (!first)
+ toAppendTo.append(LOG4CXX_STR("}"));
+ }
+ else
+ event->getMDC(m_priv->name, toAppendTo);
+}
diff --git a/src/main/cpp/odbcappender.cpp b/src/main/cpp/odbcappender.cpp
index 7a2ed5ab..8c927798 100644
--- a/src/main/cpp/odbcappender.cpp
+++ b/src/main/cpp/odbcappender.cpp
@@ -20,6 +20,7 @@
#include <log4cxx/helpers/stringhelper.h>
#include <log4cxx/helpers/transcoder.h>
#include <log4cxx/patternlayout.h>
+#include <log4cxx/pattern/mdcpatternconverter.h>
#include <apr_strings.h>
#include <apr_time.h>
#include <cmath> // std::pow
@@ -201,9 +202,29 @@ void ODBCAppender::activateOptions(log4cxx::helpers::Pool&)
auto specs = getFormatSpecifiers();
for (auto& name : _priv->mappedName)
{
- auto pItem = specs.find(StringHelper::toLowerCase(name));
+ auto lowerName = StringHelper::toLowerCase(name);
+ auto pItem = specs.find(lowerName);
if (specs.end() == pItem)
- LogLog::error(name + LOG4CXX_STR(" is not a supported ColumnMapping value"));
+ {
+ if (lowerName.size() < 3 || LOG4CXX_STR("mdc") != lowerName.substr(0, 3))
+ LogLog::error(name + LOG4CXX_STR(" is not a supported ColumnMapping value"));
+ else if (lowerName[3] == 0x7B /* '{' */) // A single MDC entry?
+ {
+ auto index = lowerName.find(0x7D /* '}' */, 4);
+ size_t len = (lowerName.npos == index ? lowerName.size() : index) - 4;
+ ODBCAppenderPriv::DataBinding paramData{ 0, 0, 0, 0, 0 };
+ paramData.converter = std::make_shared<MDCPatternConverter>(lowerName.substr(4, len));
+ _priv->parameterValue.push_back(paramData);
+ }
+ else if (lowerName.size() == 3) // Dump all MDC entries?
+ {
+ ODBCAppenderPriv::DataBinding paramData{ 0, 0, 0, 0, 0 };
+ paramData.converter = std::make_shared<MDCPatternConverter>();
+ _priv->parameterValue.push_back(paramData);
+ }
+ else
+ LogLog::error(name + LOG4CXX_STR(" is not a supported ColumnMapping value"));
+ }
else
{
ODBCAppenderPriv::DataBinding paramData{ 0, 0, 0, 0, 0 };
diff --git a/src/main/include/log4cxx/db/odbcappender.h b/src/main/include/log4cxx/db/odbcappender.h
index 60db2ccb..c842cf5e 100644
--- a/src/main/include/log4cxx/db/odbcappender.h
+++ b/src/main/include/log4cxx/db/odbcappender.h
@@ -81,18 +81,20 @@ The following <b>param</b> elements are optional:
One element for each "?" in the <b>sql</b> statement
in a sequence corresponding to the columns in the insert statement.
The following values are supported:
- - logger
- - level
- - thread
- - threadname
- - time
- - shortfilename
- - fullfilename
- - line
- - class
- - method
- - message
- - ndc
+ - <b>logger</b> - the name of the logger that generated the logging event
+ - <b>level</b> - the level of the logging event
+ - <b>thread</b> - the thread number as a hex string that generated the logging event
+ - <b>threadname</b> - the name assigned to the thread that generated the logging event
+ - <b>time</b> - a datetime or datetime2 SQL field type at which the event was generated
+ - <b>shortfilename</b> - the basename of the file containing the logging statement
+ - <b>fullfilename</b> - the path of the file containing the logging statement
+ - <b>line</b> - the position in the file at which the logging event was generated
+ - <b>class</b> - the class from which the logging event was generated
+ - <b>method</b> - the function in which the logging event was generated
+ - <b>message</b> - the data sent by the logging statement
+ - <b>mdc</b> - A JASON format string of all entries in the logging thread's mapped diagnostic context
+ - <b>mdc{key}</b> - the value associated with the <b>key</b> entry in the logging thread's mapped diagnostic context
+ - <b>ndc</b> - the last entry the logging thread's nested diagnostic context
<p>For use as a base class:
diff --git a/src/main/include/log4cxx/jsonlayout.h b/src/main/include/log4cxx/jsonlayout.h
index 0dca1d01..63affafe 100644
--- a/src/main/include/log4cxx/jsonlayout.h
+++ b/src/main/include/log4cxx/jsonlayout.h
@@ -34,7 +34,6 @@ class LOG4CXX_EXPORT JSONLayout : public Layout
LOG4CXX_DECLARE_PRIVATE_MEMBER_PTR(JSONLayoutPrivate, m_priv)
protected:
- void appendQuotedEscapedString(LogString& buf, const LogString& input) const;
void appendSerializedMDC(LogString& buf,
const spi::LoggingEventPtr& event) const;
void appendSerializedNDC(LogString& buf,
@@ -43,6 +42,7 @@ class LOG4CXX_EXPORT JSONLayout : public Layout
const spi::LoggingEventPtr& event, log4cxx::helpers::Pool& p) const;
public:
+ static void appendQuotedEscapedString(LogString& buf, const LogString& input);
DECLARE_LOG4CXX_OBJECT(JSONLayout)
BEGIN_LOG4CXX_CAST_MAP()
LOG4CXX_CAST_ENTRY(JSONLayout)
diff --git a/src/main/include/log4cxx/pattern/mdcpatternconverter.h b/src/main/include/log4cxx/pattern/mdcpatternconverter.h
new file mode 100644
index 00000000..46255ee5
--- /dev/null
+++ b/src/main/include/log4cxx/pattern/mdcpatternconverter.h
@@ -0,0 +1,57 @@
+/*
+ * 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_PATTERN_MDC_PATTERN_CONVERTER
+#define _LOG4CXX_PATTERN_MDC_PATTERN_CONVERTER
+
+#include <log4cxx/pattern/loggingeventpatternconverter.h>
+
+namespace log4cxx
+{
+namespace pattern
+{
+
+
+/**
+ * Provides all key value pairs in JASON or a single value from an event's mapped diagnostic context
+ */
+class LOG4CXX_EXPORT MDCPatternConverter : public LoggingEventPatternConverter
+{
+ public:
+ DECLARE_LOG4CXX_PATTERN(MDCPatternConverter)
+ BEGIN_LOG4CXX_CAST_MAP()
+ LOG4CXX_CAST_ENTRY(MDCPatternConverter)
+ LOG4CXX_CAST_ENTRY_CHAIN(LoggingEventPatternConverter)
+ END_LOG4CXX_CAST_MAP()
+
+ MDCPatternConverter
+ ( const LogString& name = LogString()
+ , const LogString& style = LogString()
+ , const std::vector<LogString>& options = std::vector<LogString>()
+ );
+
+ using LoggingEventPatternConverter::format;
+
+ void format
+ ( const spi::LoggingEventPtr& event
+ , LogString& toAppendTo
+ , helpers::Pool& p
+ ) const override;
+};
+}
+}
+#endif