This is an automated email from the ASF dual-hosted git repository.
rmiddleton pushed a commit to branch LOGCXX-514
in repository https://gitbox.apache.org/repos/asf/logging-log4cxx.git
The following commit(s) were added to refs/heads/LOGCXX-514 by this push:
new 3a2326ce Added some unit tests for the FMTLayout
3a2326ce is described below
commit 3a2326cea2e5a8cc2efee504803ad3789f2a0b4d
Author: Robert Middleton <[email protected]>
AuthorDate: Wed Nov 23 20:05:28 2022 -0500
Added some unit tests for the FMTLayout
---
src/main/cpp/fmtlayout.cpp | 3 +
src/main/cpp/loggingevent.cpp | 12 +-
src/main/include/log4cxx/fmtlayout.h | 16 +-
src/main/include/log4cxx/log4cxx.h.in | 3 +
src/main/include/log4cxx/spi/loggingevent.h | 3 +
src/test/cpp/CMakeLists.txt | 3 +
src/test/cpp/fmttest.cpp | 197 +++++++++++++++++++++
src/test/resources/input/fmtLayout1.properties | 21 +++
src/test/resources/input/fmtLayout10.properties | 21 +++
.../resources/input/fmtLayout1_expanded.properties | 21 +++
10 files changed, 290 insertions(+), 10 deletions(-)
diff --git a/src/main/cpp/fmtlayout.cpp b/src/main/cpp/fmtlayout.cpp
index 15ce753a..20b7cf54 100644
--- a/src/main/cpp/fmtlayout.cpp
+++ b/src/main/cpp/fmtlayout.cpp
@@ -21,8 +21,10 @@
#include <log4cxx/helpers/pool.h>
#include <log4cxx/helpers/optionconverter.h>
#include <log4cxx/level.h>
+#include <chrono>
#include <fmt/format.h>
+#include <fmt/chrono.h>
using namespace log4cxx;
using namespace log4cxx::spi;
@@ -88,6 +90,7 @@ void FMTLayout::format(LogString& output,
fmt::format_to(std::back_inserter(output),
m_priv->conversionPattern,
+ fmt::arg("d", event->getChronoTimeStamp()),
fmt::arg("c", event->getLoggerName()),
fmt::arg("logger", event->getLoggerName()),
fmt::arg("f",
event->getLocationInformation().getShortFileName()),
diff --git a/src/main/cpp/loggingevent.cpp b/src/main/cpp/loggingevent.cpp
index 8adcd0e6..f58924da 100644
--- a/src/main/cpp/loggingevent.cpp
+++ b/src/main/cpp/loggingevent.cpp
@@ -15,6 +15,7 @@
* limitations under the License.
*/
+#include <chrono>
#include <log4cxx/spi/loggingevent.h>
#include <log4cxx/ndc.h>
@@ -68,10 +69,11 @@ struct LoggingEvent::LoggingEventPrivate
ndcLookupRequired(true),
mdcCopyLookupRequired(true),
message(message1),
- timeStamp(apr_time_now()),
+ timeStamp(Date::currentTime()),
locationInfo(locationInfo1),
threadName(getCurrentThreadName()),
- threadUserName(getCurrentThreadUserName())
+ threadUserName(getCurrentThreadUserName()),
+ chronoTimeStamp(std::chrono::milliseconds(timeStamp))
{
}
@@ -138,6 +140,8 @@ struct LoggingEvent::LoggingEventPrivate
* systems or SetThreadDescription on Windows.
*/
const LogString& threadUserName;
+
+ std::chrono::time_point<std::chrono::high_resolution_clock>
chronoTimeStamp;
};
IMPLEMENT_LOG4CXX_OBJECT(LoggingEvent)
@@ -432,3 +436,7 @@ const log4cxx::spi::LocationInfo&
LoggingEvent::getLocationInformation() const
return m_priv->locationInfo;
}
+log4cxx_timepoint_t LoggingEvent::getChronoTimeStamp() const{
+ return m_priv->chronoTimeStamp;
+}
+
diff --git a/src/main/include/log4cxx/fmtlayout.h
b/src/main/include/log4cxx/fmtlayout.h
index 9bc5bbb4..79fb9e28 100644
--- a/src/main/include/log4cxx/fmtlayout.h
+++ b/src/main/include/log4cxx/fmtlayout.h
@@ -33,14 +33,14 @@ namespace log4cxx
* Most of the standard PatternLayout arguments are also accepted as
arguments, so that you can easily
* convert a PatternLayout to a FMTLayout. For example, given the following
PatternLayout:
*
- * %c %-5p - %m%n
+ * <pre>%c %-5p - %m%n</pre>
* which outputs something like:
- * root INFO - Hello there!
+ * <pre>root INFO - Hello there!</pre>
*
* The equivalent FMTLayout can be written as:
- * {c} {p:-5} - {m}{n}
+ * <pre>{c} {p:<5} - {m}{n}</pre>
* Or more verbosely as:
- * {logger} {level:-5} - {message}{newline}
+ * <pre>{logger} {level:<5} - {message}{newline}</pre>
*
* All replacements are done using the named arguments feature of {fmt}.
*
@@ -215,15 +215,15 @@ class LOG4CXX_EXPORT FMTLayout : public Layout
LOG4CXX_DECLARE_PRIVATE_MEMBER_PTR(FMTLayoutPrivate, m_priv)
public:
- DECLARE_LOG4CXX_OBJECT(FMTLayout)
+ DECLARE_LOG4CXX_OBJECT(FMTLayout)
BEGIN_LOG4CXX_CAST_MAP()
- LOG4CXX_CAST_ENTRY(FMTLayout)
+ LOG4CXX_CAST_ENTRY(FMTLayout)
LOG4CXX_CAST_ENTRY_CHAIN(Layout)
END_LOG4CXX_CAST_MAP()
- FMTLayout();
+ FMTLayout();
- FMTLayout(const LogString& pattern);
+ FMTLayout(const LogString& pattern);
~FMTLayout();
diff --git a/src/main/include/log4cxx/log4cxx.h.in
b/src/main/include/log4cxx/log4cxx.h.in
index 88470937..251be8e4 100644
--- a/src/main/include/log4cxx/log4cxx.h.in
+++ b/src/main/include/log4cxx/log4cxx.h.in
@@ -60,6 +60,9 @@ typedef unsigned int log4cxx_uint32_t;
#include "boost-std-configuration.h"
#include <memory>
+#include <chrono>
+
+typedef std::chrono::time_point<std::chrono::system_clock> log4cxx_timepoint_t;
#define LOG4CXX_PTR_DEF(T) typedef std::shared_ptr<T> T##Ptr;\
typedef std::weak_ptr<T> T##WeakPtr
diff --git a/src/main/include/log4cxx/spi/loggingevent.h
b/src/main/include/log4cxx/spi/loggingevent.h
index 55816aef..2b1ffaae 100644
--- a/src/main/include/log4cxx/spi/loggingevent.h
+++ b/src/main/include/log4cxx/spi/loggingevent.h
@@ -24,6 +24,7 @@
#include <log4cxx/mdc.h>
#include <log4cxx/spi/location/locationinfo.h>
#include <vector>
+#include <chrono>
namespace log4cxx
@@ -107,6 +108,8 @@ class LOG4CXX_EXPORT LoggingEvent :
was created. */
log4cxx_time_t getTimeStamp() const;
+ log4cxx_timepoint_t getChronoTimeStamp() const;
+
/* Return the file where this log statement was written. */
const log4cxx::spi::LocationInfo& getLocationInformation()
const;
diff --git a/src/test/cpp/CMakeLists.txt b/src/test/cpp/CMakeLists.txt
index 0e9cad93..74a35e5b 100644
--- a/src/test/cpp/CMakeLists.txt
+++ b/src/test/cpp/CMakeLists.txt
@@ -58,6 +58,9 @@ set(ALL_LOG4CXX_TESTS
locationtest
locationdisabledtest
)
+if(${ENABLE_FMT_LAYOUT})
+ set(ALL_LOG4CXX_TESTS ${ALL_LOG4CXX_TESTS} fmttest)
+endif()
foreach(fileName IN LISTS ALL_LOG4CXX_TESTS)
add_executable(${fileName} "${fileName}.cpp")
endforeach()
diff --git a/src/test/cpp/fmttest.cpp b/src/test/cpp/fmttest.cpp
new file mode 100644
index 00000000..6752e1e3
--- /dev/null
+++ b/src/test/cpp/fmttest.cpp
@@ -0,0 +1,197 @@
+/*
+ * 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 "logunit.h"
+#include "testchar.h"
+#include "util/compare.h"
+#include "util/transformer.h"
+#include "util/absolutedateandtimefilter.h"
+#include "util/iso8601filter.h"
+#include "util/absolutetimefilter.h"
+#include "util/relativetimefilter.h"
+#include "util/controlfilter.h"
+#include "util/threadfilter.h"
+#include "util/linenumberfilter.h"
+#include "util/filenamefilter.h"
+#include "vectorappender.h"
+#include <log4cxx/fmtlayout.h>
+#include <log4cxx/propertyconfigurator.h>
+#include <log4cxx/helpers/date.h>
+#include <log4cxx/spi/loggingevent.h>
+#include <iostream>
+#include <iomanip>
+
+#define REGEX_STR(x) x
+#define PAT0 REGEX_STR("\\[[0-9A-FXx]*]\\ (DEBUG|INFO|WARN|ERROR|FATAL) .* -
Message [0-9]\\{1,2\\}")
+#define PAT1 ISO8601_PAT REGEX_STR(" ") PAT0
+#define PAT2 ABSOLUTE_DATE_AND_TIME_PAT REGEX_STR(" ") PAT0
+#define PAT3 ABSOLUTE_TIME_PAT REGEX_STR(" ") PAT0
+#define PAT4 RELATIVE_TIME_PAT REGEX_STR(" ") PAT0
+#define PAT5 REGEX_STR("\\[[0-9A-FXx]*]\\ (DEBUG|INFO|WARN|ERROR|FATAL) .* :
Message [0-9]\\{1,2\\}")
+#define PAT6 REGEX_STR("\\[[0-9A-FXx]*]\\ (DEBUG|INFO |WARN |ERROR|FATAL)
.*patternlayouttest.cpp\\([0-9]\\{1,4\\}\\): Message [0-9]\\{1,3\\}")
+#define PAT11a REGEX_STR("^(DEBUG|INFO |WARN |ERROR|FATAL) \\[[0-9A-FXx]*]\\
log4j.PatternLayoutTest: Message [0-9]\\{1,2\\}")
+#define PAT11b REGEX_STR("^(DEBUG|INFO |WARN |ERROR|FATAL) \\[[0-9A-FXx]*]\\
root: Message [0-9]\\{1,2\\}")
+#define PAT12 REGEX_STR("^\\[[0-9A-FXx]*]\\ (DEBUG|INFO |WARN |ERROR|FATAL) ")\
+ REGEX_STR(".*patternlayouttest.cpp([0-9]\\{1,4\\}): ")\
+ REGEX_STR("Message [0-9]\\{1,2\\}")
+#define PAT_MDC_1 REGEX_STR("")
+
+using namespace log4cxx;
+using namespace log4cxx::helpers;
+
+LOGUNIT_CLASS(FMTTestCase)
+{
+ LOGUNIT_TEST_SUITE(FMTTestCase);
+ LOGUNIT_TEST(test1);
+ LOGUNIT_TEST(test1_expanded);
+ LOGUNIT_TEST(test10);
+ LOGUNIT_TEST(test_date);
+ LOGUNIT_TEST_SUITE_END();
+
+ LoggerPtr root;
+ LoggerPtr logger;
+
+public:
+ void setUp()
+ {
+ root = Logger::getRootLogger();
+ MDC::clear();
+ logger =
Logger::getLogger(LOG4CXX_TEST_STR("java.org.apache.log4j.PatternLayoutTest"));
+ }
+
+ void tearDown()
+ {
+ MDC::clear();
+ auto rep = root->getLoggerRepository();
+
+ if (rep)
+ {
+ rep->resetConfiguration();
+ }
+ }
+
+ void test1()
+ {
+
PropertyConfigurator::configure(LOG4CXX_FILE("input/fmtLayout1.properties"));
+ common();
+ LOGUNIT_ASSERT(Compare::compare(TEMP,
LOG4CXX_FILE("witness/patternLayout.1")));
+ }
+
+ void test1_expanded()
+ {
+
PropertyConfigurator::configure(LOG4CXX_FILE("input/fmtLayout1_expanded.properties"));
+ common();
+ LOGUNIT_ASSERT(Compare::compare(TEMP,
LOG4CXX_FILE("witness/patternLayout.1")));
+ }
+
+ void test10()
+ {
+
PropertyConfigurator::configure(LOG4CXX_FILE("input/fmtLayout10.properties"));
+ common();
+
+ ControlFilter filter1;
+ filter1 << PAT6;
+ ThreadFilter filter2;
+ LineNumberFilter filter3;
+ FilenameFilter filenameFilter(__FILE__,
"patternlayouttest.cpp");
+
+
+ std::vector<Filter*> filters;
+ filters.push_back(&filenameFilter);
+ filters.push_back(&filter1);
+ filters.push_back(&filter2);
+ filters.push_back(&filter3);
+
+
+ try
+ {
+ Transformer::transform(TEMP, FILTERED, filters);
+ }
+ catch (UnexpectedFormatException& e)
+ {
+ std::cout << "UnexpectedFormatException :" << e.what()
<< std::endl;
+ throw;
+ }
+
+ LOGUNIT_ASSERT(Compare::compare(FILTERED,
LOG4CXX_FILE("witness/patternLayout.10")));
+ }
+
+ void test_date(){
+ std::tm tm = {};
+ std::stringstream ss("2013-04-11 08:35:34");
+ ss >> std::get_time(&tm, "%Y-%m-%d %H:%M:%S");
+ auto tp =
std::chrono::system_clock::from_time_t(std::mktime(&tm));
+ uint64_t millis =
std::chrono::duration_cast<std::chrono::milliseconds>(tp.time_since_epoch()).count();
+
+ log4cxx::helpers::Date::setGetCurrentTimeFunction([millis](){
+ return millis;
+ });
+
+ log4cxx::spi::LoggingEventPtr logEvt =
std::make_shared<log4cxx::spi::LoggingEvent>( "foo",
+
Level::getInfo(),
+
"A Message",
+
log4cxx::spi::LocationInfo::getLocationUnavailable());
+ FMTLayout layout("{d:%Y-%m-%d %H:%M:%S} {message}" );
+ LogString output;
+ log4cxx::helpers::Pool pool;
+ layout.format( output, logEvt, pool);
+
+ log4cxx::helpers::Date::setGetCurrentTimeFunction(nullptr);
+
+ LOGUNIT_ASSERT_EQUAL("2013-04-11 09:35:34 A Message", output);
+ }
+
+ std::string createMessage(Pool & pool, int i)
+ {
+ std::string msg("Message ");
+ msg.append(pool.itoa(i));
+ return msg;
+ }
+
+ void common()
+ {
+ int i = -1;
+
+ Pool pool;
+
+
+ LOG4CXX_DEBUG(logger, createMessage(pool, ++i));
+ LOG4CXX_DEBUG(root, createMessage(pool, i));
+
+ LOG4CXX_INFO(logger, createMessage(pool, ++i));
+ LOG4CXX_INFO(root, createMessage(pool, i));
+
+ LOG4CXX_WARN(logger, createMessage(pool, ++i));
+ LOG4CXX_WARN(root, createMessage(pool, i));
+
+ LOG4CXX_ERROR(logger, createMessage(pool, ++i));
+ LOG4CXX_ERROR(root, createMessage(pool, i));
+
+ LOG4CXX_FATAL(logger, createMessage(pool, ++i));
+ LOG4CXX_FATAL(root, createMessage(pool, i));
+ }
+
+ private:
+ static const LogString FILTERED;
+ static const LogString TEMP;
+
+};
+
+const LogString FMTTestCase::TEMP(LOG4CXX_STR("output/fmtlayout"));
+const LogString FMTTestCase::FILTERED(LOG4CXX_STR("output/fmtlayoutfiltered"));
+
+
+LOGUNIT_TEST_SUITE_REGISTRATION(FMTTestCase);
diff --git a/src/test/resources/input/fmtLayout1.properties
b/src/test/resources/input/fmtLayout1.properties
new file mode 100644
index 00000000..ecd14df4
--- /dev/null
+++ b/src/test/resources/input/fmtLayout1.properties
@@ -0,0 +1,21 @@
+# 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.
+#
+log4j.rootCategory=DEBUG, testAppender
+log4j.appender.testAppender=org.apache.log4j.FileAppender
+log4j.appender.testAppender.file=output/fmtlayout
+log4j.appender.testAppender.Append=false
+log4j.appender.testAppender.layout=org.apache.log4j.FMTLayout
+log4j.appender.testAppender.layout.ConversionPattern={p:<5} - {m}{n}
diff --git a/src/test/resources/input/fmtLayout10.properties
b/src/test/resources/input/fmtLayout10.properties
new file mode 100644
index 00000000..3608cc74
--- /dev/null
+++ b/src/test/resources/input/fmtLayout10.properties
@@ -0,0 +1,21 @@
+# 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.
+#
+log4j.rootCategory=DEBUG, testAppender
+log4j.appender.testAppender=org.apache.log4j.FileAppender
+log4j.appender.testAppender.File= output/fmtlayout
+log4j.appender.testAppender.Append= false
+log4j.appender.testAppender.layout=org.apache.log4j.FMTLayout
+log4j.appender.testAppender.layout.ConversionPattern=[{t}] {p:<5} {l}: {m}{n}
diff --git a/src/test/resources/input/fmtLayout1_expanded.properties
b/src/test/resources/input/fmtLayout1_expanded.properties
new file mode 100644
index 00000000..70c32d8e
--- /dev/null
+++ b/src/test/resources/input/fmtLayout1_expanded.properties
@@ -0,0 +1,21 @@
+# 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.
+#
+log4j.rootCategory=DEBUG, testAppender
+log4j.appender.testAppender=org.apache.log4j.FileAppender
+log4j.appender.testAppender.file=output/fmtlayout
+log4j.appender.testAppender.Append=false
+log4j.appender.testAppender.layout=org.apache.log4j.FMTLayout
+log4j.appender.testAppender.layout.ConversionPattern={level:<5} -
{message}{newline}