From 6e2fbbff3cf388b1022c98e1c77d9b57df780881 Mon Sep 17 00:00:00 2001 From: winnerym100 Date: Sat, 10 Apr 2021 13:41:30 +0800 Subject: [PATCH 01/35] =?UTF-8?q?feature:=20=E6=B7=BB=E5=8A=A0QT=E6=97=A5?= =?UTF-8?q?=E5=BF=97=E5=BA=93?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- debian/changelog | 8 +- debian/control | 25 +- debian/copyright | 21 + debian/libukui-log4qt-dev.install | 2 + debian/libukui-log4qt0.install | 1 + debian/rules | 13 +- debian/source/format | 2 +- src/log4qt/Doxyfile | 236 ++ src/log4qt/LICENSE-2.0.txt | 202 ++ src/log4qt/README.txt | 1 + src/log4qt/debian/changelog | 11 + src/log4qt/debian/control | 25 + src/log4qt/debian/copyright | 34 + src/log4qt/debian/libukui-log4qt-dev.install | 1 + src/log4qt/debian/rules | 6 + src/log4qt/debian/source/format | 1 + src/log4qt/doc/default.css | 44 + src/log4qt/doc/index.html | 155 ++ src/log4qt/log4qt.conf | 66 + src/log4qt/log4qt/appender.h | 137 ++ src/log4qt/log4qt/appenderskeleton.cpp | 261 +++ src/log4qt/log4qt/appenderskeleton.h | 225 ++ src/log4qt/log4qt/basicconfigurator.cpp | 107 + src/log4qt/log4qt/basicconfigurator.h | 85 + src/log4qt/log4qt/consoleappender.cpp | 198 ++ src/log4qt/log4qt/consoleappender.h | 160 ++ .../log4qt/dailyrollingfileappender.cpp | 352 +++ src/log4qt/log4qt/dailyrollingfileappender.h | 197 ++ src/log4qt/log4qt/fileappender.cpp | 307 +++ src/log4qt/log4qt/fileappender.h | 233 ++ src/log4qt/log4qt/helpers/classlogger.cpp | 100 + src/log4qt/log4qt/helpers/classlogger.h | 117 + .../log4qt/helpers/configuratorhelper.cpp | 136 ++ .../log4qt/helpers/configuratorhelper.h | 211 ++ src/log4qt/log4qt/helpers/datetime.cpp | 326 +++ src/log4qt/log4qt/helpers/datetime.h | 213 ++ src/log4qt/log4qt/helpers/factory.cpp | 459 ++++ src/log4qt/log4qt/helpers/factory.h | 494 ++++ .../log4qt/helpers/initialisationhelper.cpp | 185 ++ .../log4qt/helpers/initialisationhelper.h | 437 ++++ src/log4qt/log4qt/helpers/logerror.cpp | 354 +++ src/log4qt/log4qt/helpers/logerror.h | 552 +++++ src/log4qt/log4qt/helpers/logobject.cpp | 74 + src/log4qt/log4qt/helpers/logobject.h | 218 ++ src/log4qt/log4qt/helpers/logobjectptr.cpp | 65 + src/log4qt/log4qt/helpers/logobjectptr.h | 188 ++ src/log4qt/log4qt/helpers/optionconverter.cpp | 315 +++ src/log4qt/log4qt/helpers/optionconverter.h | 151 ++ .../log4qt/helpers/patternformatter.cpp | 893 +++++++ src/log4qt/log4qt/helpers/patternformatter.h | 196 ++ src/log4qt/log4qt/helpers/properties.cpp | 364 +++ src/log4qt/log4qt/helpers/properties.h | 162 ++ src/log4qt/log4qt/hierarchy.cpp | 212 ++ src/log4qt/log4qt/hierarchy.h | 142 ++ src/log4qt/log4qt/layout.cpp | 91 + src/log4qt/log4qt/layout.h | 157 ++ src/log4qt/log4qt/level.cpp | 204 ++ src/log4qt/log4qt/level.h | 194 ++ src/log4qt/log4qt/log4qt.cpp | 58 + src/log4qt/log4qt/log4qt.h | 616 +++++ src/log4qt/log4qt/log4qt.pri | 111 + src/log4qt/log4qt/logger.cpp | 349 +++ src/log4qt/log4qt/logger.h | 1666 +++++++++++++ src/log4qt/log4qt/loggerrepository.cpp | 75 + src/log4qt/log4qt/loggerrepository.h | 129 + src/log4qt/log4qt/loggingevent.cpp | 276 +++ src/log4qt/log4qt/loggingevent.h | 222 ++ src/log4qt/log4qt/logmanager.cpp | 510 ++++ src/log4qt/log4qt/logmanager.h | 341 +++ src/log4qt/log4qt/mdc.cpp | 116 + src/log4qt/log4qt/mdc.h | 123 + src/log4qt/log4qt/ndc.cpp | 154 ++ src/log4qt/log4qt/ndc.h | 122 + src/log4qt/log4qt/patternlayout.cpp | 147 ++ src/log4qt/log4qt/patternlayout.h | 160 ++ src/log4qt/log4qt/propertyconfigurator.cpp | 588 +++++ src/log4qt/log4qt/propertyconfigurator.h | 194 ++ src/log4qt/log4qt/rollingfileappender.cpp | 191 ++ src/log4qt/log4qt/rollingfileappender.h | 164 ++ src/log4qt/log4qt/simplelayout.cpp | 84 + src/log4qt/log4qt/simplelayout.h | 102 + src/log4qt/log4qt/spi/filter.cpp | 70 + src/log4qt/log4qt/spi/filter.h | 125 + src/log4qt/log4qt/ttcclayout.cpp | 182 ++ src/log4qt/log4qt/ttcclayout.h | 235 ++ src/log4qt/log4qt/varia/debugappender.cpp | 127 + src/log4qt/log4qt/varia/debugappender.h | 134 ++ src/log4qt/log4qt/varia/denyallfilter.cpp | 77 + src/log4qt/log4qt/varia/denyallfilter.h | 105 + src/log4qt/log4qt/varia/levelmatchfilter.cpp | 100 + src/log4qt/log4qt/varia/levelmatchfilter.h | 137 ++ src/log4qt/log4qt/varia/levelrangefilter.cpp | 104 + src/log4qt/log4qt/varia/levelrangefilter.h | 153 ++ src/log4qt/log4qt/varia/listappender.cpp | 153 ++ src/log4qt/log4qt/varia/listappender.h | 174 ++ src/log4qt/log4qt/varia/nullappender.cpp | 104 + src/log4qt/log4qt/varia/nullappender.h | 102 + src/log4qt/log4qt/varia/stringmatchfilter.cpp | 101 + src/log4qt/log4qt/varia/stringmatchfilter.h | 133 ++ src/log4qt/log4qt/writerappender.cpp | 288 +++ src/log4qt/log4qt/writerappender.h | 201 ++ src/log4qt/org.ukui.log4qt-test.gschema.xml | 39 + src/log4qt/org.ukui.log4qt.gschema.xml | 49 + src/log4qt/src/log4qt/appender.h | 135 ++ src/log4qt/src/log4qt/appenderskeleton.cpp | 261 +++ src/log4qt/src/log4qt/appenderskeleton.h | 225 ++ src/log4qt/src/log4qt/basicconfigurator.cpp | 107 + src/log4qt/src/log4qt/basicconfigurator.h | 84 + src/log4qt/src/log4qt/consoleappender.cpp | 198 ++ src/log4qt/src/log4qt/consoleappender.h | 160 ++ .../src/log4qt/dailyrollingfileappender.cpp | 352 +++ .../src/log4qt/dailyrollingfileappender.h | 196 ++ src/log4qt/src/log4qt/fileappender.cpp | 307 +++ src/log4qt/src/log4qt/fileappender.h | 233 ++ src/log4qt/src/log4qt/helpers/classlogger.cpp | 100 + src/log4qt/src/log4qt/helpers/classlogger.h | 115 + .../src/log4qt/helpers/configuratorhelper.cpp | 136 ++ .../src/log4qt/helpers/configuratorhelper.h | 210 ++ src/log4qt/src/log4qt/helpers/datetime.cpp | 326 +++ src/log4qt/src/log4qt/helpers/datetime.h | 212 ++ src/log4qt/src/log4qt/helpers/factory.cpp | 459 ++++ src/log4qt/src/log4qt/helpers/factory.h | 492 ++++ .../log4qt/helpers/initialisationhelper.cpp | 185 ++ .../src/log4qt/helpers/initialisationhelper.h | 435 ++++ src/log4qt/src/log4qt/helpers/logerror.cpp | 354 +++ src/log4qt/src/log4qt/helpers/logerror.h | 550 +++++ src/log4qt/src/log4qt/helpers/logobject.cpp | 74 + src/log4qt/src/log4qt/helpers/logobject.h | 217 ++ .../src/log4qt/helpers/logobjectptr.cpp | 65 + src/log4qt/src/log4qt/helpers/logobjectptr.h | 187 ++ .../src/log4qt/helpers/optionconverter.cpp | 315 +++ .../src/log4qt/helpers/optionconverter.h | 150 ++ .../src/log4qt/helpers/patternformatter.cpp | 893 +++++++ .../src/log4qt/helpers/patternformatter.h | 195 ++ src/log4qt/src/log4qt/helpers/properties.cpp | 364 +++ src/log4qt/src/log4qt/helpers/properties.h | 161 ++ src/log4qt/src/log4qt/hierarchy.cpp | 212 ++ src/log4qt/src/log4qt/hierarchy.h | 141 ++ src/log4qt/src/log4qt/layout.cpp | 91 + src/log4qt/src/log4qt/layout.h | 156 ++ src/log4qt/src/log4qt/level.cpp | 204 ++ src/log4qt/src/log4qt/level.h | 193 ++ src/log4qt/src/log4qt/log4qt.cpp | 58 + src/log4qt/src/log4qt/log4qt.h | 614 +++++ src/log4qt/src/log4qt/log4qt.pri | 111 + src/log4qt/src/log4qt/logger.cpp | 349 +++ src/log4qt/src/log4qt/logger.h | 1665 +++++++++++++ src/log4qt/src/log4qt/loggerrepository.cpp | 75 + src/log4qt/src/log4qt/loggerrepository.h | 128 + src/log4qt/src/log4qt/loggingevent.cpp | 272 +++ src/log4qt/src/log4qt/loggingevent.h | 221 ++ src/log4qt/src/log4qt/logmanager.cpp | 504 ++++ src/log4qt/src/log4qt/logmanager.h | 340 +++ src/log4qt/src/log4qt/mdc.cpp | 116 + src/log4qt/src/log4qt/mdc.h | 122 + src/log4qt/src/log4qt/ndc.cpp | 154 ++ src/log4qt/src/log4qt/ndc.h | 121 + src/log4qt/src/log4qt/patternlayout.cpp | 147 ++ src/log4qt/src/log4qt/patternlayout.h | 159 ++ .../src/log4qt/propertyconfigurator.cpp | 588 +++++ src/log4qt/src/log4qt/propertyconfigurator.h | 194 ++ src/log4qt/src/log4qt/rollingfileappender.cpp | 191 ++ src/log4qt/src/log4qt/rollingfileappender.h | 164 ++ src/log4qt/src/log4qt/simplelayout.cpp | 84 + src/log4qt/src/log4qt/simplelayout.h | 102 + src/log4qt/src/log4qt/spi/filter.cpp | 70 + src/log4qt/src/log4qt/spi/filter.h | 124 + src/log4qt/src/log4qt/ttcclayout.cpp | 182 ++ src/log4qt/src/log4qt/ttcclayout.h | 235 ++ src/log4qt/src/log4qt/varia/debugappender.cpp | 127 + src/log4qt/src/log4qt/varia/debugappender.h | 133 ++ src/log4qt/src/log4qt/varia/denyallfilter.cpp | 77 + src/log4qt/src/log4qt/varia/denyallfilter.h | 105 + .../src/log4qt/varia/levelmatchfilter.cpp | 100 + .../src/log4qt/varia/levelmatchfilter.h | 137 ++ .../src/log4qt/varia/levelrangefilter.cpp | 104 + .../src/log4qt/varia/levelrangefilter.h | 153 ++ src/log4qt/src/log4qt/varia/listappender.cpp | 153 ++ src/log4qt/src/log4qt/varia/listappender.h | 174 ++ src/log4qt/src/log4qt/varia/nullappender.cpp | 104 + src/log4qt/src/log4qt/varia/nullappender.h | 102 + .../src/log4qt/varia/stringmatchfilter.cpp | 101 + .../src/log4qt/varia/stringmatchfilter.h | 133 ++ src/log4qt/src/log4qt/writerappender.cpp | 288 +++ src/log4qt/src/log4qt/writerappender.h | 200 ++ src/log4qt/tests/log4qttest.cpp | 2082 +++++++++++++++++ src/log4qt/tests/log4qttest.h | 177 ++ src/log4qt/tests/log4qttest.pro | 42 + src/log4qt/ukui-log4qt.cpp | 40 + src/log4qt/ukui-log4qt.h | 42 + src/log4qt/ukui-log4qt.pro | 45 + src/log4qt/ukui-logconfigurator.cpp | 382 +++ src/log4qt/ukui-logconfigurator.h | 74 + src/log4qt/ukui-logmacros.h | 53 + src/log4qt/ukui-logrolling.cpp | 175 ++ src/log4qt/ukui-logrolling.h | 63 + 196 files changed, 41619 insertions(+), 4 deletions(-) create mode 100644 debian/libukui-log4qt-dev.install create mode 100644 debian/libukui-log4qt0.install create mode 100644 src/log4qt/Doxyfile create mode 100644 src/log4qt/LICENSE-2.0.txt create mode 100644 src/log4qt/README.txt create mode 100644 src/log4qt/debian/changelog create mode 100644 src/log4qt/debian/control create mode 100644 src/log4qt/debian/copyright create mode 100644 src/log4qt/debian/libukui-log4qt-dev.install create mode 100755 src/log4qt/debian/rules create mode 100644 src/log4qt/debian/source/format create mode 100644 src/log4qt/doc/default.css create mode 100644 src/log4qt/doc/index.html create mode 100644 src/log4qt/log4qt.conf create mode 100644 src/log4qt/log4qt/appender.h create mode 100644 src/log4qt/log4qt/appenderskeleton.cpp create mode 100644 src/log4qt/log4qt/appenderskeleton.h create mode 100644 src/log4qt/log4qt/basicconfigurator.cpp create mode 100644 src/log4qt/log4qt/basicconfigurator.h create mode 100644 src/log4qt/log4qt/consoleappender.cpp create mode 100644 src/log4qt/log4qt/consoleappender.h create mode 100644 src/log4qt/log4qt/dailyrollingfileappender.cpp create mode 100644 src/log4qt/log4qt/dailyrollingfileappender.h create mode 100644 src/log4qt/log4qt/fileappender.cpp create mode 100644 src/log4qt/log4qt/fileappender.h create mode 100644 src/log4qt/log4qt/helpers/classlogger.cpp create mode 100644 src/log4qt/log4qt/helpers/classlogger.h create mode 100644 src/log4qt/log4qt/helpers/configuratorhelper.cpp create mode 100644 src/log4qt/log4qt/helpers/configuratorhelper.h create mode 100644 src/log4qt/log4qt/helpers/datetime.cpp create mode 100644 src/log4qt/log4qt/helpers/datetime.h create mode 100644 src/log4qt/log4qt/helpers/factory.cpp create mode 100644 src/log4qt/log4qt/helpers/factory.h create mode 100644 src/log4qt/log4qt/helpers/initialisationhelper.cpp create mode 100644 src/log4qt/log4qt/helpers/initialisationhelper.h create mode 100644 src/log4qt/log4qt/helpers/logerror.cpp create mode 100644 src/log4qt/log4qt/helpers/logerror.h create mode 100644 src/log4qt/log4qt/helpers/logobject.cpp create mode 100644 src/log4qt/log4qt/helpers/logobject.h create mode 100644 src/log4qt/log4qt/helpers/logobjectptr.cpp create mode 100644 src/log4qt/log4qt/helpers/logobjectptr.h create mode 100644 src/log4qt/log4qt/helpers/optionconverter.cpp create mode 100644 src/log4qt/log4qt/helpers/optionconverter.h create mode 100644 src/log4qt/log4qt/helpers/patternformatter.cpp create mode 100644 src/log4qt/log4qt/helpers/patternformatter.h create mode 100644 src/log4qt/log4qt/helpers/properties.cpp create mode 100644 src/log4qt/log4qt/helpers/properties.h create mode 100644 src/log4qt/log4qt/hierarchy.cpp create mode 100644 src/log4qt/log4qt/hierarchy.h create mode 100644 src/log4qt/log4qt/layout.cpp create mode 100644 src/log4qt/log4qt/layout.h create mode 100644 src/log4qt/log4qt/level.cpp create mode 100644 src/log4qt/log4qt/level.h create mode 100644 src/log4qt/log4qt/log4qt.cpp create mode 100644 src/log4qt/log4qt/log4qt.h create mode 100644 src/log4qt/log4qt/log4qt.pri create mode 100644 src/log4qt/log4qt/logger.cpp create mode 100644 src/log4qt/log4qt/logger.h create mode 100644 src/log4qt/log4qt/loggerrepository.cpp create mode 100644 src/log4qt/log4qt/loggerrepository.h create mode 100644 src/log4qt/log4qt/loggingevent.cpp create mode 100644 src/log4qt/log4qt/loggingevent.h create mode 100644 src/log4qt/log4qt/logmanager.cpp create mode 100644 src/log4qt/log4qt/logmanager.h create mode 100644 src/log4qt/log4qt/mdc.cpp create mode 100644 src/log4qt/log4qt/mdc.h create mode 100644 src/log4qt/log4qt/ndc.cpp create mode 100644 src/log4qt/log4qt/ndc.h create mode 100644 src/log4qt/log4qt/patternlayout.cpp create mode 100644 src/log4qt/log4qt/patternlayout.h create mode 100644 src/log4qt/log4qt/propertyconfigurator.cpp create mode 100644 src/log4qt/log4qt/propertyconfigurator.h create mode 100644 src/log4qt/log4qt/rollingfileappender.cpp create mode 100644 src/log4qt/log4qt/rollingfileappender.h create mode 100644 src/log4qt/log4qt/simplelayout.cpp create mode 100644 src/log4qt/log4qt/simplelayout.h create mode 100644 src/log4qt/log4qt/spi/filter.cpp create mode 100644 src/log4qt/log4qt/spi/filter.h create mode 100644 src/log4qt/log4qt/ttcclayout.cpp create mode 100644 src/log4qt/log4qt/ttcclayout.h create mode 100644 src/log4qt/log4qt/varia/debugappender.cpp create mode 100644 src/log4qt/log4qt/varia/debugappender.h create mode 100644 src/log4qt/log4qt/varia/denyallfilter.cpp create mode 100644 src/log4qt/log4qt/varia/denyallfilter.h create mode 100644 src/log4qt/log4qt/varia/levelmatchfilter.cpp create mode 100644 src/log4qt/log4qt/varia/levelmatchfilter.h create mode 100644 src/log4qt/log4qt/varia/levelrangefilter.cpp create mode 100644 src/log4qt/log4qt/varia/levelrangefilter.h create mode 100644 src/log4qt/log4qt/varia/listappender.cpp create mode 100644 src/log4qt/log4qt/varia/listappender.h create mode 100644 src/log4qt/log4qt/varia/nullappender.cpp create mode 100644 src/log4qt/log4qt/varia/nullappender.h create mode 100644 src/log4qt/log4qt/varia/stringmatchfilter.cpp create mode 100644 src/log4qt/log4qt/varia/stringmatchfilter.h create mode 100644 src/log4qt/log4qt/writerappender.cpp create mode 100644 src/log4qt/log4qt/writerappender.h create mode 100644 src/log4qt/org.ukui.log4qt-test.gschema.xml create mode 100644 src/log4qt/org.ukui.log4qt.gschema.xml create mode 100644 src/log4qt/src/log4qt/appender.h create mode 100644 src/log4qt/src/log4qt/appenderskeleton.cpp create mode 100644 src/log4qt/src/log4qt/appenderskeleton.h create mode 100644 src/log4qt/src/log4qt/basicconfigurator.cpp create mode 100644 src/log4qt/src/log4qt/basicconfigurator.h create mode 100644 src/log4qt/src/log4qt/consoleappender.cpp create mode 100644 src/log4qt/src/log4qt/consoleappender.h create mode 100644 src/log4qt/src/log4qt/dailyrollingfileappender.cpp create mode 100644 src/log4qt/src/log4qt/dailyrollingfileappender.h create mode 100644 src/log4qt/src/log4qt/fileappender.cpp create mode 100644 src/log4qt/src/log4qt/fileappender.h create mode 100644 src/log4qt/src/log4qt/helpers/classlogger.cpp create mode 100644 src/log4qt/src/log4qt/helpers/classlogger.h create mode 100644 src/log4qt/src/log4qt/helpers/configuratorhelper.cpp create mode 100644 src/log4qt/src/log4qt/helpers/configuratorhelper.h create mode 100644 src/log4qt/src/log4qt/helpers/datetime.cpp create mode 100644 src/log4qt/src/log4qt/helpers/datetime.h create mode 100644 src/log4qt/src/log4qt/helpers/factory.cpp create mode 100644 src/log4qt/src/log4qt/helpers/factory.h create mode 100644 src/log4qt/src/log4qt/helpers/initialisationhelper.cpp create mode 100644 src/log4qt/src/log4qt/helpers/initialisationhelper.h create mode 100644 src/log4qt/src/log4qt/helpers/logerror.cpp create mode 100644 src/log4qt/src/log4qt/helpers/logerror.h create mode 100644 src/log4qt/src/log4qt/helpers/logobject.cpp create mode 100644 src/log4qt/src/log4qt/helpers/logobject.h create mode 100644 src/log4qt/src/log4qt/helpers/logobjectptr.cpp create mode 100644 src/log4qt/src/log4qt/helpers/logobjectptr.h create mode 100644 src/log4qt/src/log4qt/helpers/optionconverter.cpp create mode 100644 src/log4qt/src/log4qt/helpers/optionconverter.h create mode 100644 src/log4qt/src/log4qt/helpers/patternformatter.cpp create mode 100644 src/log4qt/src/log4qt/helpers/patternformatter.h create mode 100644 src/log4qt/src/log4qt/helpers/properties.cpp create mode 100644 src/log4qt/src/log4qt/helpers/properties.h create mode 100644 src/log4qt/src/log4qt/hierarchy.cpp create mode 100644 src/log4qt/src/log4qt/hierarchy.h create mode 100644 src/log4qt/src/log4qt/layout.cpp create mode 100644 src/log4qt/src/log4qt/layout.h create mode 100644 src/log4qt/src/log4qt/level.cpp create mode 100644 src/log4qt/src/log4qt/level.h create mode 100644 src/log4qt/src/log4qt/log4qt.cpp create mode 100644 src/log4qt/src/log4qt/log4qt.h create mode 100644 src/log4qt/src/log4qt/log4qt.pri create mode 100644 src/log4qt/src/log4qt/logger.cpp create mode 100644 src/log4qt/src/log4qt/logger.h create mode 100644 src/log4qt/src/log4qt/loggerrepository.cpp create mode 100644 src/log4qt/src/log4qt/loggerrepository.h create mode 100644 src/log4qt/src/log4qt/loggingevent.cpp create mode 100644 src/log4qt/src/log4qt/loggingevent.h create mode 100644 src/log4qt/src/log4qt/logmanager.cpp create mode 100644 src/log4qt/src/log4qt/logmanager.h create mode 100644 src/log4qt/src/log4qt/mdc.cpp create mode 100644 src/log4qt/src/log4qt/mdc.h create mode 100644 src/log4qt/src/log4qt/ndc.cpp create mode 100644 src/log4qt/src/log4qt/ndc.h create mode 100644 src/log4qt/src/log4qt/patternlayout.cpp create mode 100644 src/log4qt/src/log4qt/patternlayout.h create mode 100644 src/log4qt/src/log4qt/propertyconfigurator.cpp create mode 100644 src/log4qt/src/log4qt/propertyconfigurator.h create mode 100644 src/log4qt/src/log4qt/rollingfileappender.cpp create mode 100644 src/log4qt/src/log4qt/rollingfileappender.h create mode 100644 src/log4qt/src/log4qt/simplelayout.cpp create mode 100644 src/log4qt/src/log4qt/simplelayout.h create mode 100644 src/log4qt/src/log4qt/spi/filter.cpp create mode 100644 src/log4qt/src/log4qt/spi/filter.h create mode 100644 src/log4qt/src/log4qt/ttcclayout.cpp create mode 100644 src/log4qt/src/log4qt/ttcclayout.h create mode 100644 src/log4qt/src/log4qt/varia/debugappender.cpp create mode 100644 src/log4qt/src/log4qt/varia/debugappender.h create mode 100644 src/log4qt/src/log4qt/varia/denyallfilter.cpp create mode 100644 src/log4qt/src/log4qt/varia/denyallfilter.h create mode 100644 src/log4qt/src/log4qt/varia/levelmatchfilter.cpp create mode 100644 src/log4qt/src/log4qt/varia/levelmatchfilter.h create mode 100644 src/log4qt/src/log4qt/varia/levelrangefilter.cpp create mode 100644 src/log4qt/src/log4qt/varia/levelrangefilter.h create mode 100644 src/log4qt/src/log4qt/varia/listappender.cpp create mode 100644 src/log4qt/src/log4qt/varia/listappender.h create mode 100644 src/log4qt/src/log4qt/varia/nullappender.cpp create mode 100644 src/log4qt/src/log4qt/varia/nullappender.h create mode 100644 src/log4qt/src/log4qt/varia/stringmatchfilter.cpp create mode 100644 src/log4qt/src/log4qt/varia/stringmatchfilter.h create mode 100644 src/log4qt/src/log4qt/writerappender.cpp create mode 100644 src/log4qt/src/log4qt/writerappender.h create mode 100644 src/log4qt/tests/log4qttest.cpp create mode 100644 src/log4qt/tests/log4qttest.h create mode 100644 src/log4qt/tests/log4qttest.pro create mode 100644 src/log4qt/ukui-log4qt.cpp create mode 100644 src/log4qt/ukui-log4qt.h create mode 100644 src/log4qt/ukui-log4qt.pro create mode 100644 src/log4qt/ukui-logconfigurator.cpp create mode 100644 src/log4qt/ukui-logconfigurator.h create mode 100644 src/log4qt/ukui-logmacros.h create mode 100644 src/log4qt/ukui-logrolling.cpp create mode 100644 src/log4qt/ukui-logrolling.h diff --git a/debian/changelog b/debian/changelog index 8e97170..b8b6e0e 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,4 +1,10 @@ -ukui-interface (1.0.0-2) UNRELEASED; urgency=low +ukui-interface (1.0.1) v101; urgency=medium + + * 增加功能:增加qt日志打印包 + + -- Yang Min Sat, 10 Apr 2021 11:49:30 +0800 + +ukui-interface (1.0.0-2) unstable; urgency=low * Set upstream metadata fields: Bug-Database, Bug-Submit. * Update standards version to 4.5.0, no changes needed. diff --git a/debian/control b/debian/control index 88f3ea4..4bed371 100644 --- a/debian/control +++ b/debian/control @@ -8,7 +8,9 @@ Build-Depends: debhelper-compat (=12), autoconf, automake, libtool, - qtbase5-dev + qtbase5-dev, + libgsettings-qt-dev, + qttools5-dev-tools Standards-Version: 4.5.0 Rules-Requires-Root: no Homepage: https://github.com/ukui/ukui-interface @@ -601,3 +603,24 @@ Description: xkbgeneral settings interfaces and related libraries. . The package contains development files for xkbgeneral settings. + +Package: libukui-log4qt0 +Architecture: any +Depends: ${shlibs:Depends}, ${misc:Depends} +Description: log4qt module + UKUI interface provides the interface for system configuration + and related libraries. + . + The package contains log4qt libraries. + +Package: libukui-log4qt-dev +Architecture: any +Section: libdevel +Depends: ${shlibs:Depends}, + ${misc:Depends}, + libukui-log4qt0 (= ${binary:Version}) +Description: log4qt interface + UKUI interface provides the interface for system configuration + and related libraries. + . + The package contains development files for qt logging. diff --git a/debian/copyright b/debian/copyright index 00597c3..91f63a8 100644 --- a/debian/copyright +++ b/debian/copyright @@ -3,6 +3,23 @@ Upstream-Name: ukui-interface Upstream-Contact: liuhao Source: https://github.com/ukui/ukui-interface +Files: src/log4qt/doc/* + src/log4qt/log4qt/* + src/log4qt/src/log4qt/* + src/log4qt/tests/* +Copyright: 2007 - 2009 Martin Heinrich +License: Apache-2.0 + +Files: src/log4qt/ukui-log4qt.h + src/log4qt/ukui-log4qt.cpp + src/log4qt/ukui-ukui-logconfigurator.h + src/log4qt/ukui-ukui-logconfigurator.cpp + src/log4qt/ukui-ukui-logrolling.h + src/log4qt/ukui-ukui-logrolling.cpp + src/log4qt/ukui-logmacros.h +Copyright: 2021 Yang Min +License: GPL-3.0+ + Files: * Copyright: 2019 Tianjin KYLIN Information Technology Co., Ltd. License: GPL-3.0+ @@ -11,6 +28,10 @@ Files: debian/* Copyright: 2019 liuhao License: GPL-3.0+ +License: Apache-2.0 + On Debian systems, the complete text of the Apache-2.0 can be found + in `/usr/share/common-licenses/Apache-2.0'. + License: GPL-3.0+ This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/debian/libukui-log4qt-dev.install b/debian/libukui-log4qt-dev.install new file mode 100644 index 0000000..436cbbd --- /dev/null +++ b/debian/libukui-log4qt-dev.install @@ -0,0 +1,2 @@ +usr/include/ukui-log4qt.h +usr/lib/libukui-log4qt.so diff --git a/debian/libukui-log4qt0.install b/debian/libukui-log4qt0.install new file mode 100644 index 0000000..9baf7fe --- /dev/null +++ b/debian/libukui-log4qt0.install @@ -0,0 +1 @@ +usr/lib/libukui-log4qt.so.* diff --git a/debian/rules b/debian/rules index b251c92..2c7f82c 100755 --- a/debian/rules +++ b/debian/rules @@ -6,12 +6,23 @@ include /usr/share/dpkg/default.mk export DEB_BUILD_MAINT_OPTIONS = hardening=+all #export DEB_CFLAGS_MAINT_APPEND = -Wall -pedantic #export DEB_LDFLAGS_MAINT_APPEND = -Wl,--as-needed - +QT_INSTALL_DIR:=$(shell pwd)/debian/tmp/ %: dh $@ +override_dh_install: + mkdir -p $(QT_INSTALL_DIR) && \ + make install INSTALL_ROOT=$(QT_INSTALL_DIR) -C src/log4qt/build + dh_install + override_dh_auto_configure: ./autogen.sh dh_auto_configure -- \ --includedir=/usr/include/ukuisdk --bindir=/usr/lib/ukui-interface + +override_dh_auto_build: + dh_auto_build + mkdir -p src/log4qt/build + cd src/log4qt/build && qmake ../ + make -C src/log4qt/build diff --git a/debian/source/format b/debian/source/format index 163aaf8..89ae9db 100644 --- a/debian/source/format +++ b/debian/source/format @@ -1 +1 @@ -3.0 (quilt) +3.0 (native) diff --git a/src/log4qt/Doxyfile b/src/log4qt/Doxyfile new file mode 100644 index 0000000..218bfe1 --- /dev/null +++ b/src/log4qt/Doxyfile @@ -0,0 +1,236 @@ +# Doxyfile 1.5.3 + +#--------------------------------------------------------------------------- +# Project related configuration options +#--------------------------------------------------------------------------- +DOXYFILE_ENCODING = UTF-8 +PROJECT_NAME = Log4Qt +PROJECT_NUMBER = +OUTPUT_DIRECTORY = doc +CREATE_SUBDIRS = NO +OUTPUT_LANGUAGE = English +BRIEF_MEMBER_DESC = YES +REPEAT_BRIEF = YES +ABBREVIATE_BRIEF = +ALWAYS_DETAILED_SEC = NO +INLINE_INHERITED_MEMB = NO +FULL_PATH_NAMES = YES +STRIP_FROM_PATH = +STRIP_FROM_INC_PATH = +SHORT_NAMES = NO +JAVADOC_AUTOBRIEF = NO +QT_AUTOBRIEF = NO +MULTILINE_CPP_IS_BRIEF = NO +DETAILS_AT_TOP = NO +INHERIT_DOCS = YES +SEPARATE_MEMBER_PAGES = NO +TAB_SIZE = 4 +ALIASES = +OPTIMIZE_OUTPUT_FOR_C = NO +OPTIMIZE_OUTPUT_JAVA = NO +BUILTIN_STL_SUPPORT = NO +CPP_CLI_SUPPORT = NO +DISTRIBUTE_GROUP_DOC = NO +SUBGROUPING = YES +#--------------------------------------------------------------------------- +# Build related configuration options +#--------------------------------------------------------------------------- +EXTRACT_ALL = YES +EXTRACT_PRIVATE = NO +EXTRACT_STATIC = NO +EXTRACT_LOCAL_CLASSES = NO +EXTRACT_LOCAL_METHODS = NO +EXTRACT_ANON_NSPACES = NO +HIDE_UNDOC_MEMBERS = NO +HIDE_UNDOC_CLASSES = NO +HIDE_FRIEND_COMPOUNDS = NO +HIDE_IN_BODY_DOCS = NO +INTERNAL_DOCS = NO +CASE_SENSE_NAMES = NO +HIDE_SCOPE_NAMES = NO +SHOW_INCLUDE_FILES = YES +INLINE_INFO = YES +SORT_MEMBER_DOCS = YES +SORT_BRIEF_DOCS = NO +SORT_BY_SCOPE_NAME = NO +GENERATE_TODOLIST = YES +GENERATE_TESTLIST = YES +GENERATE_BUGLIST = YES +GENERATE_DEPRECATEDLIST= YES +ENABLED_SECTIONS = +MAX_INITIALIZER_LINES = 30 +SHOW_USED_FILES = YES +SHOW_DIRECTORIES = NO +FILE_VERSION_FILTER = +#--------------------------------------------------------------------------- +# configuration options related to warning and progress messages +#--------------------------------------------------------------------------- +QUIET = NO +WARNINGS = YES +WARN_IF_UNDOCUMENTED = YES +WARN_IF_DOC_ERROR = YES +WARN_NO_PARAMDOC = NO +WARN_FORMAT = "$file:$line: $text " +WARN_LOGFILE = +#--------------------------------------------------------------------------- +# configuration options related to the input files +#--------------------------------------------------------------------------- +INPUT = +INPUT_ENCODING = UTF-8 +FILE_PATTERNS = +RECURSIVE = YES +EXCLUDE = +EXCLUDE_SYMLINKS = NO +EXCLUDE_PATTERNS = *_p.h \ + *.cpp +EXCLUDE_SYMBOLS = +EXAMPLE_PATH = +EXAMPLE_PATTERNS = +EXAMPLE_RECURSIVE = NO +IMAGE_PATH = +INPUT_FILTER = +FILTER_PATTERNS = +FILTER_SOURCE_FILES = NO +#--------------------------------------------------------------------------- +# configuration options related to source browsing +#--------------------------------------------------------------------------- +SOURCE_BROWSER = NO +INLINE_SOURCES = NO +STRIP_CODE_COMMENTS = YES +REFERENCED_BY_RELATION = YES +REFERENCES_RELATION = YES +REFERENCES_LINK_SOURCE = YES +USE_HTAGS = NO +VERBATIM_HEADERS = YES +#--------------------------------------------------------------------------- +# configuration options related to the alphabetical class index +#--------------------------------------------------------------------------- +ALPHABETICAL_INDEX = NO +COLS_IN_ALPHA_INDEX = 5 +IGNORE_PREFIX = +#--------------------------------------------------------------------------- +# configuration options related to the HTML output +#--------------------------------------------------------------------------- +GENERATE_HTML = YES +HTML_OUTPUT = html +HTML_FILE_EXTENSION = .html +HTML_HEADER = +HTML_FOOTER = +HTML_STYLESHEET = +HTML_ALIGN_MEMBERS = YES +GENERATE_HTMLHELP = NO +HTML_DYNAMIC_SECTIONS = NO +CHM_FILE = +HHC_LOCATION = +GENERATE_CHI = NO +BINARY_TOC = NO +TOC_EXPAND = NO +DISABLE_INDEX = NO +ENUM_VALUES_PER_LINE = 4 +GENERATE_TREEVIEW = NO +TREEVIEW_WIDTH = 250 +#--------------------------------------------------------------------------- +# configuration options related to the LaTeX output +#--------------------------------------------------------------------------- +GENERATE_LATEX = NO +LATEX_OUTPUT = latex +LATEX_CMD_NAME = latex +MAKEINDEX_CMD_NAME = makeindex +COMPACT_LATEX = NO +PAPER_TYPE = a4wide +EXTRA_PACKAGES = +LATEX_HEADER = +PDF_HYPERLINKS = NO +USE_PDFLATEX = NO +LATEX_BATCHMODE = NO +LATEX_HIDE_INDICES = NO +#--------------------------------------------------------------------------- +# configuration options related to the RTF output +#--------------------------------------------------------------------------- +GENERATE_RTF = NO +RTF_OUTPUT = rtf +COMPACT_RTF = NO +RTF_HYPERLINKS = NO +RTF_STYLESHEET_FILE = +RTF_EXTENSIONS_FILE = +#--------------------------------------------------------------------------- +# configuration options related to the man page output +#--------------------------------------------------------------------------- +GENERATE_MAN = NO +MAN_OUTPUT = man +MAN_EXTENSION = .3 +MAN_LINKS = NO +#--------------------------------------------------------------------------- +# configuration options related to the XML output +#--------------------------------------------------------------------------- +GENERATE_XML = NO +XML_OUTPUT = xml +XML_SCHEMA = +XML_DTD = +XML_PROGRAMLISTING = YES +#--------------------------------------------------------------------------- +# configuration options for the AutoGen Definitions output +#--------------------------------------------------------------------------- +GENERATE_AUTOGEN_DEF = NO +#--------------------------------------------------------------------------- +# configuration options related to the Perl module output +#--------------------------------------------------------------------------- +GENERATE_PERLMOD = NO +PERLMOD_LATEX = NO +PERLMOD_PRETTY = YES +PERLMOD_MAKEVAR_PREFIX = +#--------------------------------------------------------------------------- +# Configuration options related to the preprocessor +#--------------------------------------------------------------------------- +ENABLE_PREPROCESSING = YES +MACRO_EXPANSION = YES +EXPAND_ONLY_PREDEF = YES +SEARCH_INCLUDES = YES +INCLUDE_PATH = +INCLUDE_FILE_PATTERNS = +PREDEFINED = Q_CORE_EXPORT=\ \ + "Q_DECLARE_FLAGS(Flags, Enum)=typedef QFlags Flags; " \ + Q_WS_WIN=1 \ + Q_WS_MAC=1 \ + Q_WS_X11=1 +EXPAND_AS_DEFINED = +SKIP_FUNCTION_MACROS = YES +#--------------------------------------------------------------------------- +# Configuration::additions related to external references +#--------------------------------------------------------------------------- +TAGFILES = +GENERATE_TAGFILE = +ALLEXTERNALS = NO +EXTERNAL_GROUPS = YES +PERL_PATH = +#--------------------------------------------------------------------------- +# Configuration options related to the dot tool +#--------------------------------------------------------------------------- +CLASS_DIAGRAMS = YES +MSCGEN_PATH = +HIDE_UNDOC_RELATIONS = YES +HAVE_DOT = NO +CLASS_GRAPH = YES +COLLABORATION_GRAPH = YES +GROUP_GRAPHS = YES +UML_LOOK = NO +TEMPLATE_RELATIONS = NO +INCLUDE_GRAPH = YES +INCLUDED_BY_GRAPH = YES +CALL_GRAPH = NO +CALLER_GRAPH = NO +GRAPHICAL_HIERARCHY = YES +DIRECTORY_GRAPH = YES +DOT_IMAGE_FORMAT = png +DOT_PATH = +DOTFILE_DIRS = +DOT_GRAPH_MAX_NODES = 50 +MAX_DOT_GRAPH_DEPTH = 0 +DOT_TRANSPARENT = NO +DOT_MULTI_TARGETS = NO +GENERATE_LEGEND = YES +DOT_CLEANUP = YES +#--------------------------------------------------------------------------- +# Configuration::additions related to the search engine +#--------------------------------------------------------------------------- +SEARCHENGINE = NO diff --git a/src/log4qt/LICENSE-2.0.txt b/src/log4qt/LICENSE-2.0.txt new file mode 100644 index 0000000..d645695 --- /dev/null +++ b/src/log4qt/LICENSE-2.0.txt @@ -0,0 +1,202 @@ + + 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 [yyyy] [name of copyright owner] + + 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. diff --git a/src/log4qt/README.txt b/src/log4qt/README.txt new file mode 100644 index 0000000..1fbddd7 --- /dev/null +++ b/src/log4qt/README.txt @@ -0,0 +1 @@ +See HTML documentation under doc/index.html \ No newline at end of file diff --git a/src/log4qt/debian/changelog b/src/log4qt/debian/changelog new file mode 100644 index 0000000..981557d --- /dev/null +++ b/src/log4qt/debian/changelog @@ -0,0 +1,11 @@ +log4qt (1.0.1) v101; urgency=medium + + * Fix:修复qt开启宏QT_NO_DEBUG时log输出的代码位置信息为空异常 + + -- Yang Min Tue, 30 Mar 2021 19:25:20 +0800 + +log4qt (1.0.0) v101; urgency=medium + + * Initial release. + + -- Yang Min Tue, 30 Mar 2021 16:29:55 +0800 diff --git a/src/log4qt/debian/control b/src/log4qt/debian/control new file mode 100644 index 0000000..43e560f --- /dev/null +++ b/src/log4qt/debian/control @@ -0,0 +1,25 @@ +Source: log4qt +Section: libs +Priority: optional +Maintainer: Kylin Team +Uploaders: Yang Min +Build-Depends: debhelper-compat (=12), + qt5-qmake, + qtbase5-dev, + qtbase5-dev-tools, + qtbase5-private-dev, + libgsettings-qt-dev +Standards-Version: 4.5.1 +Rules-Requires-Root: no +Homepage: https://sourceforge.net/projects/log4qt/files/ +Vcs-Git: https://github.com/devbean/log4qt.git +Vcs-Browser: https://github.com/devbean/log4qt + +Package: libukui-log4qt-dev +Section: libdevel +Architecture: any +Depends: ${misc:Depends}, + ${shlibs:Depends} +Description: Development files for the Log4Qt library + Log4Qt is a C++ port of the Apache Software Foundation + Log4j package using the Trolltech Qt Framework. diff --git a/src/log4qt/debian/copyright b/src/log4qt/debian/copyright new file mode 100644 index 0000000..4ccd190 --- /dev/null +++ b/src/log4qt/debian/copyright @@ -0,0 +1,34 @@ +Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ +Upstream-Name: log4qt +Source: + +Files: * + doc/* + log4qt/* + src/log4qt/* + tests/* +Copyright: 2007 - 2009 Martin Heinrich +License: Apache-2.0 + +Files: debian/* +Copyright: 2020 Tianjin KYLIN Information Technology Co., Ltd. +License: GPL-3.0+ + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + . + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + . + You should have received a copy of the GNU General Public License + along with this program. If not, see . + . + On Debian systems, the complete text of the GNU General Public License + Version 3 can be found in `/usr/share/common-licenses/GPL-3'. + +License: Apache-2.0 + On Debian systems, the complete text of the Apache-2.0 can be found + in `/usr/share/common-licenses/Apache-2.0'. diff --git a/src/log4qt/debian/libukui-log4qt-dev.install b/src/log4qt/debian/libukui-log4qt-dev.install new file mode 100644 index 0000000..e19765e --- /dev/null +++ b/src/log4qt/debian/libukui-log4qt-dev.install @@ -0,0 +1 @@ +ukui-log4qt.h usr/include/ diff --git a/src/log4qt/debian/rules b/src/log4qt/debian/rules new file mode 100755 index 0000000..52ed6f4 --- /dev/null +++ b/src/log4qt/debian/rules @@ -0,0 +1,6 @@ +#!/usr/bin/make -f +export QT_SELECT=5 +export DEB_BUILD_MAINT_OPTIONS = hardening=+all + +%: + dh $@ diff --git a/src/log4qt/debian/source/format b/src/log4qt/debian/source/format new file mode 100644 index 0000000..89ae9db --- /dev/null +++ b/src/log4qt/debian/source/format @@ -0,0 +1 @@ +3.0 (native) diff --git a/src/log4qt/doc/default.css b/src/log4qt/doc/default.css new file mode 100644 index 0000000..d619f8d --- /dev/null +++ b/src/log4qt/doc/default.css @@ -0,0 +1,44 @@ +BODY,H1,H2,H3,H4,H5,H6,P,CENTER,TD,TH,UL,DL,DIV { + font-family: Geneva, Arial, Helvetica, sans-serif; +} +BODY,TD { + font-size: 90%; +} +H1 { + text-align: center; + font-size: 160%; +} +H2 { + font-size: 120%; +} +H3 { + font-size: 100%; +} +H2 { + background-color: #e8eef2; + color: #1a419d; + font-weight: bold; + padding-right : 10px; + padding-top : 2px; + padding-left : 10px; + padding-bottom : 2px; + margin-left : 0px; + margin-right : 0px; + margin-top : 2px; + margin-bottom : 2px; + border: 1px solid #cccccc; +} +A { + text-decoration: none; + font-weight: bold; + color: #1A419D; +} +A:visited { + text-decoration: none; + font-weight: bold; + color: #1A419D +} +A:hover { + text-decoration: none; + background-color: #ddddff; +} diff --git a/src/log4qt/doc/index.html b/src/log4qt/doc/index.html new file mode 100644 index 0000000..7b79fbc --- /dev/null +++ b/src/log4qt/doc/index.html @@ -0,0 +1,155 @@ + + + + Log4Qt + + + + +

Log4Qt

+

Introduction

+

+Log4Qt is a C++ port of the Apache Software Foundation Log4j package using the +Trolltech Qt Framework. It is intended to be used by open source and commercial +Qt projects. +

+ +

Documentation

+

+The documentation describes classes and methods that have been added or changed +compared to Log4j. The documentation was generated from the source code using +Doxygen. It can be accessed here. +

+ +

How to use

+

+To use Log4Qt within your software project include the Log4Qt source into your project +

    +
  1. + Download the package from the + SourceForge project page +
  2. + Unpack the Log4Qt package +
  3. + Add the log4qt source to the Qt project file by adding the following line
    + include(<unpackdir>/src/log4qt/log4qt.pri) +
  4. + Include the Logger class, a layout and an appender class to configure Log4Qt to generate output. The example uses the ConsoleAppender with a TTCCLayout
    + include "log4qt/consoleappender.h"
    + include "log4qt/logger.h"
    + include "log4qt/ttcclayout.h" +
  5. + Configure a logger to generate output. The example uses the root logger
    + // Create a layout
    + Log4Qt::LogManager::rootLogger();
    + TTCCLayout *p_layout = new TTCCLayout();
    + p_layout->setName(QLatin1String("My Layout"));
    + p_layout->activateOptions();
    + // Create an appender
    + ConsoleAppender *p_appender = new ConsoleAppender(p_layout, ConsoleAppender::STDOUT_TARGET);
    + p_appender->setName(QLatin1String("My Appender"));
    + p_appender->activateOptions();
    + // Set appender on root logger
    + Log4Qt::Logger::rootLogger()->setAppender(p_appender); +
  6. + Request a logger by either calling Log4Qt::Logger::logger or using LOG4QT_DECLARE_QCLASS_LOGGER
    + // Request a logger and output "Hello World!"
    + Log4Qt::Logger::logger(QLatin1String("My Logger"))->info("Hello World!");
    +
  7. +
+

+ +

Releases

+

+

    +
  • + 0.3 - 01 March 2009
    + Bug fixes, compatibility with VS 2008 and Qt 4.5 RC1 +
      +
    • + Fixed a problem where the pParent parameter of the constructor was not passed on to the QObject constructor (logobject.h) +
    • +
    • + Fixed a problem were OptionConverter::toBoolean would not return the default value, if the conversion fails (optionconverter.cpp) +
    • +
    • + Fixed a compile error on VS 2008 by using Q_UNUSED(&rEvent) instead of Q_UNUSED(rEvent) (varia/denyallfilter.h.h) +
    • +
    • + Fixed VS 2008 unreferenced formal parameter warning by using Q_UNUSED (logmanager.cpp, mdc.cpp, ndc.cpp, propertyconfigurator.cpp, helpers/initialisationhelper.cpp, helpers/patternformatter.cpp) +
    • +
    +
  • +
  • + 0.2 - 30 January 2009
    + Bug fixes and compatibility with Qt 4.4 +
      +
    • + Added a compile time version check for the Qt version (log4qt.h) +
    • +
    • + Replaced usage of q_atomic_increment and q_atomic_decrement with QAtomicInt for compilation with Qt 4.4 (helpers/logobject.h) +
    • +
    • + Replaced usage of q_atomic_test_and_set_ptr with QAtomicPointer for compilation with Qt 4.4 (logger.h, helpers/classlogger.cpp, helpers/classlogger.h, helpers/initialisationhelper.h) +
    • +
    • + Fixed a problem with Qt 4.4 where QReadWriteLock is by default non-recursive (hierarchy.cpp, logger.cpp) +
    • +
    • + Resolved compilation problem with Microsoft Visual Studio 2005 (logmanager.cpp, helpers/datetime.cpp) +
    • +
    +
  • +
  • + 0.1 - 29 December 2007
    + Initial Version +
  • +
+

+ +

Known Problems

+

+

    +
  • + The Eclipse CDT console does not display the log output of a correctly + when using a ConsoleAppender with a TTCCLayout and relative time format. + The millisecond count is stripped from the output. +
  • +
+

+ +

License

+

+Log4Qt is licensed under the +Apache License Version 2.0. +

+

+Log4Qt requires the Qt framework that is available under several licensing options +(Qt licensing). +The package is intended to be used under the +Nokia Corporation Qt GPL Exception. +

+ +

Links

+

+

+

+ +

+
+ + + + + +
SourceForge.net LogoXX February 2009, Martin Heinrich
+

+ + diff --git a/src/log4qt/log4qt.conf b/src/log4qt/log4qt.conf new file mode 100644 index 0000000..bb9c8e3 --- /dev/null +++ b/src/log4qt/log4qt.conf @@ -0,0 +1,66 @@ +#设置储存log文件的根目录 +logpath=. + +#全局设置 +#是否重置所有配置,恢复全局设置默认值 +log4j.reset=true +#设置Log4Qt记录器输入级别 +log4j.Debug=INFO +#日志记录器存储库的阈值 +log4j.threshold=NULL +#设置是否监听QDebug输出的字符串 +log4j.handleQtMessages=true + +#设置根Logger的输出log等级为INFO +#设置Log输出的几种输出源(appender):console, daily +log4j.rootLogger=DEBUG,console,daily + +#设置终端打印记录器 +#记录器类别 --控制台输出 +log4j.appender.console=org.apache.log4j.ConsoleAppender +#记录器输出目标 +log4j.appender.console.target=STDOUT_TARGET +#记录器输出布局 (包含日志产生的时间、线程、类别等信息) +log4j.appender.console.layout=org.apache.log4j.TTCCLayout +#记录器布局日期格式 (年-月-日 时:分:秒.毫秒) +log4j.appender.console.layout.dateFormat=yyy-MM-dd hh:mm:ss.zzz +#记录器布局包含上下文 +log4j.appender.console.layout.contextPrinting=false +#记录器布局包含线程信息 +#log4j.appender.console.layout.ThreadPrinting=false + +#设置一个每日储存一个log文件的记录器 +#记录器类别 --一天一个文件输出 +log4j.appender.daily=org.apache.log4j.DailyRollingFileAppender +#记录器输出文件路径 +log4j.appender.daily.file=${logpath}/log4qt.log +#记录器追加文件内容 +log4j.appender.daily.appendFile=true +#记录器是否直接写入文件 +#log4j.appender.daily.immediateFlush=true +#记录器文件名日期后缀 按天 +log4j.appender.daily.datePattern=.yyyy-MM-dd +#记录器布局分隔符 (根据patten符号格式化输出数据,类似printf的格式化方式) +log4j.appender.daily.layout=org.apache.log4j.PatternLayout +log4j.appender.daily.layout.conversionPattern=%-5p|%d{yyyy-MM-dd HH:mm:ss,zzz}(%-4r)|%m%n +#记录器输出格式 +#日志信息格式中几个符号所代表的含义: +# -X号: X信息输出时左对齐; +# %p: 输出日志信息优先级,即DEBUG,INFO,WARN,ERROR,FATAL, +# %d: 输出日志时间点的日期或时间,默认格式为ISO8601,也可以在其后指定格式,比如:%d{yyy MMM dd HH:mm:ss,SSS},输出类似:2002年10月18日 22:10:28,921 +# %r: 输出自应用启动到输出该log信息耗费的毫秒数 +# %c: 输出日志信息所属的类目,通常就是所在类的全名 (无效) +# %t: 输出产生该日志事件的线程名 (无效) +# %l: 输出日志事件的发生位置,相当于%C.%M(%F:%L)的组合,包括类目名、发生的线程,以及在代码中的行数(无效)。举例:Testlog4.main (TestLog4.java:10) +# %x: 输出和当前线程相关联的NDC(嵌套诊断环境),尤其用到像java servlets这样的多客户多线程的应用中。 +# %%: 输出一个"%"字符 +# %F: 输出日志消息产生时所在的文件名称(无效) +# %L: 输出代码中的行号(无效) +# %m: 输出代码中指定的消息,产生的日志具体信息(默认在消息内容前追加了文件名,行号,函数名) +# %n: 输出一个回车换行符,Windows平台为"\r\n",Unix平台为"\n"输出日志信息换行 +# 可以在%与模式字符之间加上修饰符来控制其最小宽度、最大宽度、和文本的对齐方式。如: +# 1) c:指定输出category的名称,最小的宽度是20,如果category的名称小于20的话,默认的情况下右对齐。 +# 2)%-20c:指定输出category的名称,最小的宽度是20,如果category的名称小于20的话,"-"号指定左对齐。 +# 3)%.30c:指定输出category的名称,最大的宽度是30,如果category的名称大于30的话,就会将左边多出的字符截掉,但小于30的话也不会有空格。 +# 4) .30c:如果category的名称小于20就补空格,并且右对齐,如果其名称长于30字符,就从左边较远输出的字符截掉。 + diff --git a/src/log4qt/log4qt/appender.h b/src/log4qt/log4qt/appender.h new file mode 100644 index 0000000..cb7a217 --- /dev/null +++ b/src/log4qt/log4qt/appender.h @@ -0,0 +1,137 @@ +/****************************************************************************** + * + * package: Log4Qt + * file: appender.h + * created: September 2007 + * author: Martin Heinrich + * + * + * Copyright 2007 Martin Heinrich + * + * 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. + * + ********************************************************************************/ + +#ifndef LOG4QT_APPENDER_H +#define LOG4QT_APPENDER_H + + +/****************************************************************************** + * Dependencies + ******************************************************************************/ + +#include "log4qt/helpers/logobject.h" + +#include "log4qt/helpers/logobjectptr.h" + +#include "log4qt/logger.h" + +#include "ukui-logmacros.h" + + +/****************************************************************************** + * Declarations + ******************************************************************************/ + +namespace Log4Qt +{ + + class Filter; + class Layout; + class LoggingEvent; + + /*! + * \brief The class Appender is the base class for all Appenders. + * + * To allow the whole hirarchy to be an ascendant of QObject Appender is + * not an interface. + * + * \note All the functions declared in this class are thread-safe. + * + * \note The ownership and lifetime of objects of this class are managed. + * See \ref Ownership "Object ownership" for more details. + */ + class LIBUKUILOG4QT_EXPORT Appender : public LogObject + { + Q_OBJECT + + /*! + * The property holds the Layout used by the Appender. + * + * \sa layout(), setLayout() + */ + Q_PROPERTY(Layout* layout READ layout WRITE setLayout) + + /*! + * The property holds the name of the Appender. + * + * \sa name(), setName() + */ + Q_PROPERTY(QString name READ name WRITE setName) + + /*! + * The property holds if the Appender requires a Layout or not. + * + * \sa requiresLayout(), setRequiresLayout() + */ + Q_PROPERTY(bool requiresLayout READ requiresLayout) + + public: + Appender(QObject *pParent = 0); + virtual ~Appender(); + private: + Appender(const Appender &rOther); // Not implemented + Appender &operator=(const Appender &rOther); // Not implemented + + public: + // JAVA: ErrorHandler* errorHandler(); + virtual Filter *filter() const = 0; + virtual QString name() const = 0; + virtual Layout *layout() const = 0; + virtual bool requiresLayout() const = 0; + // JAVA: void setErrorHandler(ErrorHandler *pErrorHandler); + virtual void setLayout(Layout *pLayout) = 0; + virtual void setName(const QString &rName) = 0; + + virtual void addFilter(Filter *pFilter) = 0; + virtual void clearFilters() = 0; + virtual void close() = 0; + virtual void doAppend(const LoggingEvent &rEvent) = 0; + }; + + + /************************************************************************** + * Operators, Helper + **************************************************************************/ + + + /************************************************************************** + * Inline + **************************************************************************/ + + inline Appender::Appender(QObject *pParent) : + LogObject(pParent) + {} + + inline Appender::~Appender() + {} + + +} // namespace Log4Qt + + +// Q_DECLARE_TYPEINFO(Log4Qt::Appender, Q_COMPLEX_TYPE); // Use default +Q_DECLARE_TYPEINFO(Log4Qt::LogObjectPtr, Q_MOVABLE_TYPE); + + +#endif // LOG4QT_APPENDER_H diff --git a/src/log4qt/log4qt/appenderskeleton.cpp b/src/log4qt/log4qt/appenderskeleton.cpp new file mode 100644 index 0000000..d9f784b --- /dev/null +++ b/src/log4qt/log4qt/appenderskeleton.cpp @@ -0,0 +1,261 @@ +/****************************************************************************** + * + * package: Log4Qt + * file: appenderskeleton.cpp + * created: September 2007 + * author: Martin Heinrich + * + * + * Copyright 2007 Martin Heinrich + * + * 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. + * + ******************************************************************************/ + + + +/****************************************************************************** + * Dependencies + ******************************************************************************/ + + +#include "log4qt/appenderskeleton.h" + +#include +#include "log4qt/layout.h" +#include "log4qt/loggingevent.h" +#include "log4qt/logmanager.h" +#include "log4qt/spi/filter.h" + + +namespace Log4Qt +{ + + + /************************************************************************** + * Declarations + ***************************************************************************/ + + + /*! + * \brief The class RecursionGuardLocker controls a boolean flag. + * + * It is a helper class to control a boolean flag. The class sets the flag + * on creation and resets it on destruction. + */ + class RecursionGuardLocker + { + public: + RecursionGuardLocker(bool *pGuard); + ~RecursionGuardLocker(); + private: + RecursionGuardLocker(const RecursionGuardLocker &rOther); // Not implemented + RecursionGuardLocker &operator=(const RecursionGuardLocker &rOther); // Not implemented + private: + bool *mpGuard; + }; + + + + /************************************************************************** + * C helper functions + **************************************************************************/ + + + + /************************************************************************** + * Class implementation: RecursionGuardLocker + ***************************************************************************/ + + + inline RecursionGuardLocker::RecursionGuardLocker(bool *pGuard) + { + Q_ASSERT_X(pGuard != 0, "RecursionGuardLocker::RecursionGuardLocker()", "Pointer to guard bool must not be null"); + + mpGuard = pGuard; + *mpGuard = true; + } + + + inline RecursionGuardLocker::~RecursionGuardLocker() + { + *mpGuard = false; + }; + + + + /************************************************************************** + * Class implementation: AppenderSkeleton + **************************************************************************/ + + + AppenderSkeleton::AppenderSkeleton(QObject *pParent) : + Appender(pParent), + mObjectGuard(QMutex::Recursive), // Recursive for doAppend() + mAppendRecursionGuard(false), + mIsActive(true), + mIsClosed(false), + mpLayout(0), + mThreshold(Level::NULL_INT), + mpHeadFilter(0), + mpTailFilter(0) + { + } + + + AppenderSkeleton::AppenderSkeleton(const bool isActive, + QObject *pParent) : + Appender(pParent), + mObjectGuard(QMutex::Recursive), // Recursive for doAppend() + mAppendRecursionGuard(false), + mIsActive(isActive), + mIsClosed(false), + mpLayout(0), + mThreshold(Level::NULL_INT), + mpHeadFilter(0), + mpTailFilter(0) + { + } + + + void AppenderSkeleton::activateOptions() + { + QMutexLocker locker(&mObjectGuard); + + if (requiresLayout() && !layout()) + { + LogError e = LOG4QT_QCLASS_ERROR(QT_TR_NOOP("Activation of appender '%1' that requires layout and has no layout set"), + APPENDER_ACTIVATE_MISSING_LAYOUT_ERROR); + e << name(); + logger()->error(e); + return; + } + mIsActive = true; + } + + + void AppenderSkeleton::addFilter(Filter *pFilter) + { + if(!pFilter) + { + logger()->warn("Adding null Filter to Appender '%1'", name()); + return; + } + + QMutexLocker locker(&mObjectGuard); + + mpTailFilter = pFilter; + if (mpHeadFilter) + mpHeadFilter->setNext(pFilter); + else + mpHeadFilter = pFilter; + } + + + void AppenderSkeleton::clearFilters() + { + QMutexLocker locker(&mObjectGuard); + + mpTailFilter = 0; + mpHeadFilter = 0; + } + + + void AppenderSkeleton::close() + { + QMutexLocker locker(&mObjectGuard); + + mIsClosed = true; + mIsActive = false; + } + + + void AppenderSkeleton::doAppend(const LoggingEvent &rEvent) + { + // The mutex serialises concurrent access from multiple threads. + // - e.g. two threads using the same logger + // - e.g. two threads using different logger with the same appender + // + // A call from the same thread will pass the mutex (QMutex::Recursive) + // and get to the recursion guard. The recursion guard blocks recursive + // invocation and prevents a possible endless loop. + // - e.g. an appender logs an error with a logger that uses it + + QMutexLocker locker(&mObjectGuard); + + if (mAppendRecursionGuard) + return; + + RecursionGuardLocker recursion_locker(&mAppendRecursionGuard); + + if (!checkEntryConditions()) + return; + if (!isAsSevereAsThreshold(rEvent.level())) + return; + + Filter *p_filter = mpHeadFilter; + while(p_filter) + { + Filter::Decision decision = p_filter->decide(rEvent); + if (decision == Filter::ACCEPT) + break; + else if (decision == Filter::DENY) + return; + else + p_filter = p_filter->next(); + } + + append(rEvent); + } + + + bool AppenderSkeleton::checkEntryConditions() const + { + // Q_ASSERT_X(, "WriterAppender::checkEntryConditions()", "Lock must be held by caller") + + if (!isActive()) + { + LogError e = LOG4QT_QCLASS_ERROR(QT_TR_NOOP("Use of non activated appender '%1'"), + APPENDER_NOT_ACTIVATED_ERROR); + e << name(); + logger()->error(e); + return false; + } + if (isClosed()) + { + LogError e = LOG4QT_QCLASS_ERROR(QT_TR_NOOP("Use of closed appender '%1'"), + APPENDER_CLOSED_ERROR); + e << name(); + logger()->error(e); + return false; + } + if (requiresLayout() && !layout()) + { + LogError e = LOG4QT_QCLASS_ERROR(QT_TR_NOOP("Use of appender '%1' that requires layout and has no layout set"), + APPENDER_USE_MISSING_LAYOUT_ERROR); + e << name(); + logger()->error(e); + return false; + } + + return true; + } + + + + /************************************************************************** + * Implementation: Operators, Helper + **************************************************************************/ + + +} // namespace Log4Qt diff --git a/src/log4qt/log4qt/appenderskeleton.h b/src/log4qt/log4qt/appenderskeleton.h new file mode 100644 index 0000000..4101e1d --- /dev/null +++ b/src/log4qt/log4qt/appenderskeleton.h @@ -0,0 +1,225 @@ +/****************************************************************************** + * + * package: Log4Qt + * file: appenderskeleton.h + * created: September 2007 + * author: Martin Heinrich + * + * + * Copyright 2007 Martin Heinrich + * + * 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. + * + ******************************************************************************/ + +#ifndef LOG4QT_APPENDERSKELETON_H +#define LOG4QT_APPENDERSKELETON_H + + +/****************************************************************************** + * Dependencies +******************************************************************************/ + +#include "log4qt/appender.h" + +#include +#include "log4qt/helpers/logobjectptr.h" +#include "ukui-logmacros.h" + +/****************************************************************************** + * Declarations + ******************************************************************************/ + +namespace Log4Qt +{ + + class Filter; + class Layout; + class Logger; + class LoggingEvent; + + /*! + * \brief The class AppenderSkeleton implements general Appender functionality. + * + * \note All the functions declared in this class are thread-safe. + * + * \note The ownership and lifetime of objects of this class are managed. See + * \ref Ownership "Object ownership" for more details. + */ + class LIBUKUILOG4QT_EXPORT AppenderSkeleton : public Appender + { + Q_OBJECT + + /*! + * The property holds if the Appender has been activated. + * + * \sa isActive() + */ + Q_PROPERTY(bool isActive READ isActive) + + /*! + * The property holds if the Appender has been closed. + * + * \sa isClosed() + */ + Q_PROPERTY(bool isClosed READ isClosed) + + /*! + * The property holds the threshold level used by the Appender. + * + * \sa threshold(), setThreshold() + */ + Q_PROPERTY(Level threshold READ threshold WRITE setThreshold) + + public: + AppenderSkeleton(QObject *pParent = 0); + protected: + AppenderSkeleton(const bool isActive, + QObject *pParent = 0); + public: + // virtual ~AppenderSkeleton(); Use compiler default + private: + AppenderSkeleton(const AppenderSkeleton &rOther); // Not implemented + AppenderSkeleton &operator=(const AppenderSkeleton &rOther); // Not implemented + + public: + // JAVA: ErrorHandler* errorHandler(); + virtual Filter *filter() const; + virtual Layout *layout() const; + bool isActive() const; + bool isClosed() const; + virtual QString name() const; + Level threshold() const; + // JAVA: void setErrorHandler(ErrorHandler *pErrorHandler); + virtual void setLayout(Layout *pLayout); + virtual void setName(const QString &rName); + void setThreshold(Level level); + + virtual void activateOptions(); + virtual void addFilter(Filter *pFilter); + virtual void clearFilters(); + virtual void close(); + + /*! + * Performs checks and delegates the actuall appending to the subclass + * specific append() function. + * + * \sa append(), checkEntryConditions(), isAsSevereAsThreshold(), Filter + */ + virtual void doAppend(const LoggingEvent &rEvent); + + // JAVA: void finalize(); + Filter* firstFilter() const; + bool isAsSevereAsThreshold(Level level) const; + + protected: + virtual void append(const LoggingEvent &rEvent) = 0; + + /*! + * Tests if all entry conditions for using append() in this class are + * met. + * + * If a conditions is not met, an error is logged and the function + * returns false. + * + * The checked conditions are: + * - That the appender has been activated (APPENDER_NOT_ACTIVATED_ERROR) + * - That the appender was not closed (APPENDER_CLOSED_ERROR) + * - That the appender has a layout set, if it requires one + * (logging_error(APPENDER_USE_MISSING_LAYOUT_ERROR) + * + * The function is called as part of the checkEntryConditions() chain + * started by doAppend(). The doAppend() function calls the subclass + * specific checkEntryConditions() function. The function checks the + * class specific conditions and calls checkEntryConditions() of + * it's parent class. The last function called is + * AppenderSkeleton::checkEntryConditions(). + * + * \sa doAppend() + */ + virtual bool checkEntryConditions() const; + + protected: + mutable QMutex mObjectGuard; + private: + bool mAppendRecursionGuard; + volatile bool mIsActive; + volatile bool mIsClosed; + LogObjectPtr mpLayout; + Level mThreshold; + LogObjectPtr mpHeadFilter; + LogObjectPtr mpTailFilter; + }; + + + /************************************************************************** + * Operators, Helper + **************************************************************************/ + + + /************************************************************************** + * Inline + **************************************************************************/ + + inline Filter *AppenderSkeleton::filter() const + { QMutexLocker locker(&mObjectGuard); + return mpHeadFilter; } + + inline Layout *AppenderSkeleton::layout() const + { QMutexLocker locker(&mObjectGuard); + return mpLayout; } + + inline QString AppenderSkeleton::name() const + { QMutexLocker locker(&mObjectGuard); + return objectName(); } + + inline Level AppenderSkeleton::threshold() const + { // QMutexLocker locker(&mObjectGuard); // Level is threadsafe + return mThreshold; } + + inline void AppenderSkeleton::setLayout(Layout *pLayout) + { QMutexLocker locker(&mObjectGuard); + mpLayout = pLayout; } + + inline void AppenderSkeleton::setName(const QString &rName) + { QMutexLocker locker(&mObjectGuard); + setObjectName(rName); } + + inline void AppenderSkeleton::setThreshold(Level level) + { // QMutexLocker locker(&mObjectGuard); // Level is threadsafe + mThreshold = level; } + + inline bool AppenderSkeleton::isActive() const + { // QMutexLocker locker(&mObjectGuard); // Read/Write of int is safe + return mIsActive; } + + inline bool AppenderSkeleton::isClosed() const + { // QMutexLocker locker(&mObjectGuard); // Read/Write of int is safe + return mIsClosed; } + + inline Filter *AppenderSkeleton::firstFilter() const + { QMutexLocker locker(&mObjectGuard); + return filter(); } + + inline bool AppenderSkeleton::isAsSevereAsThreshold(Level level) const + { // QMutexLocker locker(&mObjectGuard); // Level is threadsafe + return (mThreshold <= level); } + + +} // namespace Log4Qt + + +// Q_DECLARE_TYPEINFO(Log4Qt::AppenderSkeleton, Q_COMPLEX_TYPE); // Use default + + +#endif // LOG4QT_APPENDERSKELETON_H diff --git a/src/log4qt/log4qt/basicconfigurator.cpp b/src/log4qt/log4qt/basicconfigurator.cpp new file mode 100644 index 0000000..280b88d --- /dev/null +++ b/src/log4qt/log4qt/basicconfigurator.cpp @@ -0,0 +1,107 @@ +/****************************************************************************** + * + * package: Log4Qt + * file: basicconfigurator.cpp + * created: September 2007 + * author: Martin Heinrich + * + * + * Copyright 2007 Martin Heinrich + * + * 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. + * + ******************************************************************************/ + + + +/****************************************************************************** + * Dependencies + ******************************************************************************/ + + +#include "log4qt/basicconfigurator.h" + +#include +#include +#include +#include "log4qt/consoleappender.h" +#include "log4qt/helpers/configuratorhelper.h" +#include "log4qt/helpers/logobjectptr.h" +#include "log4qt/logmanager.h" +#include "log4qt/patternlayout.h" +#include "log4qt/varia/listappender.h" + + + +namespace Log4Qt +{ + + + /************************************************************************** + * Declarations + **************************************************************************/ + + + + /************************************************************************** + * C helper functions + **************************************************************************/ + + + + /************************************************************************** + * Class implementation: BasicConfigurator + **************************************************************************/ + + + bool BasicConfigurator::configure() + { + LogObjectPtr list = new ListAppender; + list->setName(QLatin1String("BasicConfigurator")); + list->setConfiguratorList(true); + list->setThreshold(Level::ERROR_INT); + LogManager::logLogger()->addAppender(list); + + PatternLayout *p_layout = new PatternLayout(PatternLayout::TTCC_CONVERSION_PATTERN); + p_layout->setName(QLatin1String("BasicConfigurator TTCC")); + p_layout->activateOptions(); + ConsoleAppender *p_appender = new ConsoleAppender(p_layout, ConsoleAppender::STDOUT_TARGET); + p_appender->setName(QLatin1String("BasicConfigurator stdout")); + p_appender->activateOptions(); + LogManager::rootLogger()->addAppender(p_appender); + + LogManager::logLogger()->removeAppender(list); + ConfiguratorHelper::setConfigureError(list->list()); + return (list->list().count() == 0); + } + + + void BasicConfigurator::configure(Appender *pAppender) + { + LogManager::rootLogger()->addAppender(pAppender); + } + + + void BasicConfigurator::resetConfiguration() + { + LogManager::resetConfiguration(); + } + + + + /************************************************************************** + * Implementation: Operators, Helper + **************************************************************************/ + + +} // namespace Log4Qt diff --git a/src/log4qt/log4qt/basicconfigurator.h b/src/log4qt/log4qt/basicconfigurator.h new file mode 100644 index 0000000..5dfa62f --- /dev/null +++ b/src/log4qt/log4qt/basicconfigurator.h @@ -0,0 +1,85 @@ +/****************************************************************************** + * + * package: Log4Qt + * file: basicconfigurator.h + * created: September 2007 + * author: Martin Heinrich + * + * + * Copyright 2007 Martin Heinrich + * + * 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. + * + ******************************************************************************/ + +#ifndef LOG4QT_BASICCONFIGURATOR_H +#define LOG4QT_BASICCONFIGURATOR_H + + +/****************************************************************************** + * Dependencies + ******************************************************************************/ + + +#include +#include "log4qt/log4qt.h" +#include "ukui-logmacros.h" + + +/****************************************************************************** + * Declarations + ******************************************************************************/ + +namespace Log4Qt +{ + + class Appender; + + /*! + * \brief The class BasicConfigurator provides a simple package + * configuration. + * + * \note All the functions declared in this class are thread-safe. + */ + class LIBUKUILOG4QT_EXPORT BasicConfigurator + { + private: + BasicConfigurator(); // Not implemented + // BasicConfigurator(const BasicConfigurator &rOther); // Use compiler default + // virtual ~BasicConfigurator(); // Use compiler default + // BasicConfigurator &operator=(const BasicConfigurator &rOther); // Use compiler default + + public: + static bool configure(); + static void configure(Appender *pAppender); + static void resetConfiguration(); + }; + + + /************************************************************************** + * Operators, Helper + **************************************************************************/ + + + /************************************************************************** + * Inline + **************************************************************************/ + + +} // namspace Log4Qt + + +// Q_DECLARE_TYPEINFO(Log4Qt::BasicConfigurator, Q_MOVABLE_TYPE); // Use default + + +#endif // LOG4QT_BASICCONFIGURATOR_H diff --git a/src/log4qt/log4qt/consoleappender.cpp b/src/log4qt/log4qt/consoleappender.cpp new file mode 100644 index 0000000..1b4fe03 --- /dev/null +++ b/src/log4qt/log4qt/consoleappender.cpp @@ -0,0 +1,198 @@ +/****************************************************************************** + * + * package: Log4Qt + * file: consoleappender.cpp + * created: September 2007 + * author: Martin Heinrich + * + * + * Copyright 2007 Martin Heinrich + * + * 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. + * + ******************************************************************************/ + + + +/****************************************************************************** + * Dependencies + ******************************************************************************/ + + +#include "log4qt/consoleappender.h" + +#include +#include +#include "log4qt/helpers/optionconverter.h" +#include "log4qt/layout.h" +#include "log4qt/loggingevent.h" + + + +namespace Log4Qt +{ + + + /************************************************************************** + * Declarations + **************************************************************************/ + + + + /************************************************************************** + * C helper functions + **************************************************************************/ + + + + /************************************************************************** + * Class implementation: ConsoleAppender + **************************************************************************/ + + + ConsoleAppender::ConsoleAppender(QObject *pParent) : + WriterAppender(pParent), + mTarget(STDOUT_TARGET), + mpTextStream(0) + { + } + + + ConsoleAppender::ConsoleAppender(Layout *pLayout, + QObject *pParent) : + WriterAppender(pLayout, pParent), + mTarget(STDOUT_TARGET), + mpTextStream(0) + { + } + + + ConsoleAppender::ConsoleAppender(Layout *pLayout, + const QString &rTarget, + QObject *pParent) : + WriterAppender(pLayout, pParent), + mTarget(STDOUT_TARGET), + mpTextStream(0) + { + setTarget(rTarget); + } + + + ConsoleAppender::ConsoleAppender(Layout *pLayout, + Target target, + QObject *pParent) : + WriterAppender(pLayout, pParent), + mTarget(target), + mpTextStream(0) + { + } + + + ConsoleAppender::~ConsoleAppender() + { + close(); + } + + + QString ConsoleAppender::target() const + { + // QMutexLocker locker(&mObjectGuard); // Read/Write of int is safe + + if (mTarget == STDOUT_TARGET) + return QLatin1String("STDOUT_TARGET"); + else + return QLatin1String("STDERR_TARGET"); + } + + + void ConsoleAppender::setTarget(const QString &rTarget) + { + bool ok; + Target target = (Target)OptionConverter::toTarget(rTarget, &ok); + if (ok) + setTarget(target); + } + + + void ConsoleAppender::activateOptions() + { + QMutexLocker locker(&mObjectGuard); + + closeStream(); + + if (mTarget == STDOUT_TARGET) + mpTextStream = new QTextStream(stdout); + else + mpTextStream = new QTextStream(stderr); + setWriter(mpTextStream); + + WriterAppender::activateOptions(); + } + + + void ConsoleAppender::close() + { + QMutexLocker locker(&mObjectGuard); + + if (isClosed()) + return; + + WriterAppender::close(); + closeStream(); + } + + + void ConsoleAppender::closeStream() + { + // Q_ASSERT_X(, "ConsoleAppender::closeStream()", "Lock must be held by caller") + + setWriter(0); + delete mpTextStream; + mpTextStream = 0; + } + + +#ifndef QT_NO_DEBUG_STREAM + QDebug ConsoleAppender::debug(QDebug &rDebug) const + { + QString layout_name; + if (layout()) + layout_name = layout()->name(); + QString target; + if (mTarget == STDOUT_TARGET) + target = QLatin1String("STDOUT"); + else + target = QLatin1String("STDERR"); + + rDebug.nospace() << "ConsoleAppender(" + << "name:" << name() << " " + << "filter:" << firstFilter() << " " + << "isactive:" << isActive() << " " + << "isclosed:" << isClosed() << " " + << "layout:" << layout_name << " " + << "target:" << target << " " + << "referencecount:" << referenceCount() << " " + << "threshold:" << threshold().toString() + << ")"; + return rDebug.space(); + } +#endif // QT_NO_DEBUG_STREAM + + + + /****************************************************************************** + * Implementation: Operators, Helper + ******************************************************************************/ + + +} // namespace Log4Qt diff --git a/src/log4qt/log4qt/consoleappender.h b/src/log4qt/log4qt/consoleappender.h new file mode 100644 index 0000000..17fd969 --- /dev/null +++ b/src/log4qt/log4qt/consoleappender.h @@ -0,0 +1,160 @@ +/****************************************************************************** + * + * package: Log4Qt + * file: consoleappender.h + * created: September 2007 + * author: Martin Heinrich + * + * + * Copyright 2007 Martin Heinrich + * + * 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. + * + ******************************************************************************/ + +#ifndef LOG4QT_CONSOLEAPPENDER_H +#define LOG4QT_CONSOLEAPPENDER_H + + +/****************************************************************************** + * Dependencies + ******************************************************************************/ + +#include "log4qt/writerappender.h" +#include "ukui-logmacros.h" + +/****************************************************************************** + * Declarations + ******************************************************************************/ + +class QFile; +class QTextStream; + +namespace Log4Qt +{ + + /*! + * \brief The class ConsoleAppender appends to stdout or stderr. + * + * \note All the functions declared in this class are thread-safe. + * + * \note The ownership and lifetime of objects of this class are managed. + * See \ref Ownership "Object ownership" for more details. + */ + class LIBUKUILOG4QT_EXPORT ConsoleAppender : public WriterAppender + { + Q_OBJECT + + /*! + * The property holds the target used by the appender. + * + * The default is STDOUT_TARGET for the standard output. + * + * \sa Target, target(), setTarget() + */ + Q_PROPERTY(QString target READ target WRITE setTarget) + + public: + /*! + * The enum defines the possible output targets + * + * \sa target(), setTarget() + */ + enum Target { + /*! The output target is standard out. */ + STDOUT_TARGET, + /*! The output target is standard error. */ + STDERR_TARGET + }; + Q_ENUMS(Target) + + ConsoleAppender(QObject *pParent = 0); + ConsoleAppender(Layout *pLayout, + QObject *pParent = 0); + ConsoleAppender(Layout *pLayout, + const QString &rTarget, + QObject *pParent = 0); + + /*! + * Creates a ConsoleAppender with the layout \a pLayout, the target + * value specified by the \a target constant and the parent + * \a pParent. + */ + ConsoleAppender(Layout *pLayout, + Target target, + QObject *pParent = 0); + + virtual ~ConsoleAppender(); + private: + ConsoleAppender(const ConsoleAppender &rOther); // Not implemented + ConsoleAppender &operator=(const ConsoleAppender &rOther); // Not implemented + + public: + // JAVA: bool follow() const; + QString target() const; + // JAVA: void setFollow(bool follow); + void setTarget(const QString &rTarget); + + /*! + * Sets the target to the value specified by the \a target constant. + */ + void setTarget(Target target); + + virtual void activateOptions(); + virtual void close(); + + protected: + void closeStream(); + + #ifndef QT_NO_DEBUG_STREAM + /*! + * Writes all object member variables to the given debug stream + * \a rDebug and returns the stream. + * + * + * %ConsoleAppender(name:"CA" filter:0x0 isactive:true isclosed:false + * layout:"PL" target:"STDERR" referenceCount:1 + * threshold:"WARN_SET") + * + * \sa QDebug, operator<<(QDebug debug, const LogObject &rLogObject) + */ + virtual QDebug debug(QDebug &rDebug) const; + #endif // QT_NO_DEBUG_STREAM + + private: + volatile Target mTarget; + QTextStream *mpTextStream; + }; + + + /************************************************************************** + * Operators, Helper + **************************************************************************/ + + + /************************************************************************** + * Inline + **************************************************************************/ + + inline void ConsoleAppender::setTarget(Target target) + { // QMutexLocker locker(&mObjectGuard); // Read/Write of int is safe + mTarget = target; } + + +} // namespace Log4Qt + + +// Q_DECLARE_TYPEINFO(Log4Qt::ConsoleAppender, Q_COMPLEX_TYPE); // Use default + + +#endif // LOG4QT_CONSOLEAPPENDER_H diff --git a/src/log4qt/log4qt/dailyrollingfileappender.cpp b/src/log4qt/log4qt/dailyrollingfileappender.cpp new file mode 100644 index 0000000..0590f16 --- /dev/null +++ b/src/log4qt/log4qt/dailyrollingfileappender.cpp @@ -0,0 +1,352 @@ +/****************************************************************************** + * + * package: Log4Qt + * file: dailyrollingfileappender.cpp + * created: September 2007 + * author: Martin Heinrich + * + * + * Copyright 2007 Martin Heinrich + * + * 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. + * + ******************************************************************************/ + + + +/****************************************************************************** + * Dependencies + ******************************************************************************/ + + +#include "log4qt/dailyrollingfileappender.h" + +#include +#include +#include +#include +#include "log4qt/helpers/datetime.h" +#include "log4qt/layout.h" +#include "log4qt/loggingevent.h" + + + +namespace Log4Qt +{ + + + /************************************************************************** + * Declarations + **************************************************************************/ + + + + /************************************************************************** + * C helper functions + **************************************************************************/ + + + + /************************************************************************** + * Class implementation: DailyRollingFileAppender + **************************************************************************/ + + + DailyRollingFileAppender::DailyRollingFileAppender(QObject *pParent) : + FileAppender(pParent), + mDatePattern() + { + setDatePattern(DAILY_ROLLOVER); + } + + + DailyRollingFileAppender::DailyRollingFileAppender(Layout *pLayout, + const QString &rFileName, + const QString &rDatePattern, + QObject *pParent) : + FileAppender(pLayout, rFileName, pParent), + mDatePattern() + { + setDatePattern(rDatePattern); + } + + + DailyRollingFileAppender::~DailyRollingFileAppender() + { + close(); + } + + + void DailyRollingFileAppender::setDatePattern(DatePattern datePattern) + { + switch (datePattern) + { + case MINUTELY_ROLLOVER: + setDatePattern(QLatin1String("'.'yyyy-MM-dd-hh-mm")); + break; + case HOURLY_ROLLOVER: + setDatePattern(QLatin1String("'.'yyyy-MM-dd-hh")); + break; + case HALFDAILY_ROLLOVER: + setDatePattern(QLatin1String("'.'yyyy-MM-dd-a")); + break; + case DAILY_ROLLOVER: + setDatePattern(QLatin1String("'.'yyyy-MM-dd")); + break; + case WEEKLY_ROLLOVER: + setDatePattern(QLatin1String("'.'yyyy-ww")); + break; + case MONTHLY_ROLLOVER: + setDatePattern(QLatin1String("'.'yyyy-MM")); + break; + default: + Q_ASSERT_X(false, "DailyRollingFileAppender::setDatePattern()", "Invalid datePattern constant"); + setDatePattern(DAILY_ROLLOVER); + }; + } + + + void DailyRollingFileAppender::activateOptions() + { + QMutexLocker locker(&mObjectGuard); + + computeFrequency(); + if (!mActiveDatePattern.isEmpty()) + { + computeRollOverTime(); + FileAppender::activateOptions(); + } + } + + + void DailyRollingFileAppender::append(const LoggingEvent &rEvent) + { + // Q_ASSERT_X(, "DailyRollingFileAppender::append()", "Lock must be held by caller") + + if (QDateTime::currentDateTime() > mRollOverTime) + rollOver(); + FileAppender::append(rEvent); + } + + + bool DailyRollingFileAppender::checkEntryConditions() const + { + // Q_ASSERT_X(, "DailyRollingFileAppender::checkEntryConditions()", "Lock must be held by caller") + + if (mActiveDatePattern.isEmpty()) + { + LogError e = LOG4QT_QCLASS_ERROR(QT_TR_NOOP("Use of appender '%1' without having a valid date pattern set"), + APPENDER_USE_INVALID_PATTERN_ERROR); + e << name(); + logger()->error(e); + return false; + } + + return FileAppender::checkEntryConditions(); + } + + +#ifndef QT_NO_DEBUG_STREAM + QDebug DailyRollingFileAppender::debug(QDebug &rDebug) const + { + QString layout_name; + if (layout()) + layout_name = layout()->name(); + QString codec_name; + if (encoding()) + codec_name = QLatin1String(encoding()->name()); + + rDebug.nospace() << "DailyRollingFileAppender(" + << "name:" << name() << " " + << "activedatepattern:" << mActiveDatePattern << " " + << "appendfile:" << appendFile() << " " + << "bufferedio:" << bufferedIo() << " " + << "datepattern:" << datePattern() << " " + << "encoding:" << codec_name << " " + << "frequency:" << frequencyToString() << " " + << "file:" << file() << " " + << "filter:" << firstFilter() << " " + << "immediateflush:" << immediateFlush() << " " + << "isactive:" << isActive() << " " + << "isclosed:" << isClosed() << " " + << "layout:" << layout_name << " " + << "referencecount:" << referenceCount() << " " + << "rollovertime:" << mRollOverTime + << "threshold:" << threshold().toString() + << "writer:" << writer() + << ")"; + return rDebug.space(); + } +#endif // QT_NO_DEBUG_STREAM + + + void DailyRollingFileAppender::computeFrequency() + { + // Q_ASSERT_X(, "DailyRollingFileAppender::computeFrequency()", "Lock must be held by caller") + + const DateTime start_time(QDate(1999, 1, 1), QTime(0, 0)); + const QString start_string = start_time.toString(mDatePattern); + mActiveDatePattern.clear(); + + if (start_string != static_cast(start_time.addSecs(60)).toString(mDatePattern)) + mFrequency = MINUTELY_ROLLOVER; + else if (start_string != static_cast(start_time.addSecs(60 * 60)).toString(mDatePattern)) + mFrequency = HOURLY_ROLLOVER; + else if (start_string != static_cast(start_time.addSecs(60 * 60 * 12)).toString(mDatePattern)) + mFrequency = HALFDAILY_ROLLOVER; + else if (start_string != static_cast(start_time.addDays(1)).toString(mDatePattern)) + mFrequency = DAILY_ROLLOVER; + else if (start_string != static_cast(start_time.addDays(7)).toString(mDatePattern)) + mFrequency = WEEKLY_ROLLOVER; + else if (start_string != static_cast(start_time.addMonths(1)).toString(mDatePattern)) + mFrequency = MONTHLY_ROLLOVER; + else + { + LogError e = LOG4QT_QCLASS_ERROR(QT_TR_NOOP("The pattern '%1' does not specify a frequency for appender '%2'"), + APPENDER_INVALID_PATTERN_ERROR); + e << mDatePattern << name(); + logger()->error(e); + return; + } + + mActiveDatePattern = mDatePattern; + logger()->trace("Frequency set to %2 using date pattern %1", + mActiveDatePattern, + frequencyToString()); + } + + + void DailyRollingFileAppender::computeRollOverTime() + { + // Q_ASSERT_X(, "DailyRollingFileAppender::computeRollOverTime()", "Lock must be held by caller") + Q_ASSERT_X(!mActiveDatePattern.isEmpty(), "DailyRollingFileAppender::computeRollOverTime()", "No active date pattern"); + + QDateTime now = QDateTime::currentDateTime(); + QDate now_date = now.date(); + QTime now_time = now.time(); + QDateTime start; + + switch (mFrequency) + { + case MINUTELY_ROLLOVER: + { + start = QDateTime(now_date, + QTime(now_time.hour(), + now_time.minute(), + 0, 0)); + mRollOverTime = start.addSecs(60); + } + break; + case HOURLY_ROLLOVER: + { + start = QDateTime(now_date, + QTime(now_time.hour(), + 0, 0, 0)); + mRollOverTime = start.addSecs(60*60); + } + break; + case HALFDAILY_ROLLOVER: + { + int hour = now_time.hour(); + if (hour >= 12) + hour = 12; + else + hour = 0; + start = QDateTime(now_date, + QTime(hour, 0, 0, 0)); + mRollOverTime = start.addSecs(60*60*12); + } + break; + case DAILY_ROLLOVER: + { + start = QDateTime(now_date, + QTime(0, 0, 0, 0)); + mRollOverTime = start.addDays(1); + } + break; + case WEEKLY_ROLLOVER: + { + // QT numbers the week days 1..7. The week starts on Monday. + // Change it to being numbered 0..6, starting with Sunday. + int day = now_date.dayOfWeek(); + if (day == Qt::Sunday) + day = 0; + start = QDateTime(now_date, + QTime(0, 0, 0, 0)).addDays(-1 * day); + mRollOverTime = start.addDays(7); + } + break; + case MONTHLY_ROLLOVER: + { + start = QDateTime(QDate(now_date.year(), + now_date.month(), + 1), + QTime(0, 0, 0, 0)); + mRollOverTime = start.addMonths(1); + } + break; + default: + Q_ASSERT_X(false, "DailyRollingFileAppender::computeInterval()", "Invalid datePattern constant"); + mRollOverTime = QDateTime::fromTime_t(0); + } + + mRollOverSuffix = static_cast(start).toString(mActiveDatePattern); + Q_ASSERT_X(static_cast(now).toString(mActiveDatePattern) == mRollOverSuffix, + "DailyRollingFileAppender::computeRollOverTime()", "File name changes within interval"); + Q_ASSERT_X(mRollOverSuffix != static_cast(mRollOverTime).toString(mActiveDatePattern), + "DailyRollingFileAppender::computeRollOverTime()", "File name does not change with rollover"); + + logger()->trace("Computing roll over time from %1: The interval start time is %2. The roll over time is %3", + now, + start, + mRollOverTime); + } + + + QString DailyRollingFileAppender::frequencyToString() const + { + QMetaEnum meta_enum = metaObject()->enumerator(metaObject()->indexOfEnumerator("DatePattern")); + return QLatin1String(meta_enum.valueToKey(mFrequency)); + } + + + void DailyRollingFileAppender::rollOver() + { + // Q_ASSERT_X(, "DailyRollingFileAppender::rollOver()", "Lock must be held by caller") + Q_ASSERT_X(!mActiveDatePattern.isEmpty(), "DailyRollingFileAppender::rollOver()", "No active date pattern"); + + QString roll_over_suffix = mRollOverSuffix; + computeRollOverTime(); + if (roll_over_suffix == mRollOverSuffix) + return; + + closeFile(); + + QString target_file_name = file() + roll_over_suffix; + QFile f(target_file_name); + if (f.exists() && !removeFile(f)) + return; + f.setFileName(file()); + if (!renameFile(f, target_file_name)) + return; + openFile(); + } + + + + /************************************************************************** + * Implementation: Operators, Helper + **************************************************************************/ + + +} // namespace Log4Qt diff --git a/src/log4qt/log4qt/dailyrollingfileappender.h b/src/log4qt/log4qt/dailyrollingfileappender.h new file mode 100644 index 0000000..f293b40 --- /dev/null +++ b/src/log4qt/log4qt/dailyrollingfileappender.h @@ -0,0 +1,197 @@ +/****************************************************************************** + * + * package: Log4Qt + * file: dailyrollingfileappender.h + * created: September 2007 + * author: Martin Heinrich + * + * + * Copyright 2007 Martin Heinrich + * + * 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. + * + ******************************************************************************/ + +#ifndef LOG4QT_DAILYROLLINGFILEAPPENDER_H +#define LOG4QT_DAILYROLLINGFILEAPPENDER_H + + +/****************************************************************************** + * Dependencies + ******************************************************************************/ + +#include "log4qt/fileappender.h" +#include "ukui-logmacros.h" + +#include + + +/****************************************************************************** + * Declarations + ******************************************************************************/ + +namespace Log4Qt +{ + + /*! + * \brief The class DailyRollingFileAppender extends FileAppender so that the + * underlying file is rolled over at a specified frequency. + * + * \note All the functions declared in this class are thread-safe. + * + * \note The ownership and lifetime of objects of this class are managed. See + * \ref Ownership "Object ownership" for more details. + */ + class LIBUKUILOG4QT_EXPORT DailyRollingFileAppender : public FileAppender + { + Q_OBJECT + + /*! + * The property holds the date pattern used by the appender. + * + * The default is DAILY_ROLLOVER for rollover at midnight each day. + * + * \sa datePattern(), setDatePattern() + */ + Q_PROPERTY(QString datePattern READ datePattern WRITE setDatePattern) + + public: + /*! + * The enum DatePattern defines constants for date patterns. + * + * \sa setDatePattern(DatePattern) + */ + enum DatePattern + { + /*! The minutely date pattern string is "'.'yyyy-MM-dd-hh-mm". */ + MINUTELY_ROLLOVER = 0, + /*! The hourly date pattern string is "'.'yyyy-MM-dd-hh". */ + HOURLY_ROLLOVER, + /*! The half-daily date pattern string is "'.'yyyy-MM-dd-a". */ + HALFDAILY_ROLLOVER, + /*! The daily date pattern string is "'.'yyyy-MM-dd". */ + DAILY_ROLLOVER, + /*! The weekly date pattern string is "'.'yyyy-ww". */ + WEEKLY_ROLLOVER, + /*! The monthly date pattern string is "'.'yyyy-MM". */ + MONTHLY_ROLLOVER + }; + Q_ENUMS(DatePattern) + + DailyRollingFileAppender(QObject *pParent = 0); + DailyRollingFileAppender(Layout *pLayout, + const QString &rFileName, + const QString &rDatePattern, + QObject *pParent = 0); + virtual ~DailyRollingFileAppender(); + private: + DailyRollingFileAppender(const DailyRollingFileAppender &rOther); // Not implemented + DailyRollingFileAppender &operator=(const DailyRollingFileAppender &rOther); // Not implemented + + public: + QString datePattern() const; + + /*! + * Sets the datePattern to the value specified by the \a datePattern + * constant. + */ + void setDatePattern(DatePattern datePattern); + + void setDatePattern(const QString &rDatePattern); + + virtual void activateOptions(); + + protected: + virtual void append(const LoggingEvent &rEvent); + + /*! + * Tests if all entry conditions for using append() in this class are + * met. + * + * If a conditions is not met, an error is logged and the function + * returns false. Otherwise the result of + * FileAppender::checkEntryConditions() is returned. + * + * The checked conditions are: + * - A valid pattern has been set (APPENDER_USE_INVALID_PATTERN_ERROR) + * + * The function is called as part of the checkEntryConditions() chain + * started by AppenderSkeleton::doAppend(). + * + * \sa AppenderSkeleton::doAppend(), + * AppenderSkeleton::checkEntryConditions() + */ + virtual bool checkEntryConditions() const; + + protected: +#ifndef QT_NO_DEBUG_STREAM + /*! + * Writes all object member variables to the given debug stream + * \a rDebug and returns the stream. + * + * + * %DailyRollingFileAppender(name:"DRFA" activedatepattern:"'.'yyyy-MM-dd-hh-mm" + * appendfile:false bufferedio:true + * datepattern:"'.'yyyy-MM-dd-hh-mm" + * encoding:"" frequency:"MINUTELY_ROLLOVER" + * file:"/log.txt" filter:0x0 immediateflush:true + * isactive:true isclosed:false layout:"TTCC" + * referencecount:1 + * rollovertime:QDateTime("Mon Oct 22 05:23:00 2007") + * threshold: "NULL" writer: 0x0 ) + * + * \sa QDebug, operator<<(QDebug debug, const LogObject &rLogObject) + */ + virtual QDebug debug(QDebug &rDebug) const; +#endif // QT_NO_DEBUG_STREAM + + private: + void computeFrequency(); + void computeRollOverTime(); + QString frequencyToString() const; + void rollOver(); + + private: + QString mDatePattern; + DatePattern mFrequency; + QString mActiveDatePattern; + QDateTime mRollOverTime; + QString mRollOverSuffix; + }; + + + /************************************************************************** + * Operators, Helper + **************************************************************************/ + + + /************************************************************************** + * Inline + **************************************************************************/ + + inline QString DailyRollingFileAppender::datePattern() const + { QMutexLocker locker(&mObjectGuard); + return mDatePattern; } + + inline void DailyRollingFileAppender::setDatePattern(const QString &rDatePattern) + { QMutexLocker locker(&mObjectGuard); + mDatePattern = rDatePattern; } + + +} // namespace Log4Qt + + +// Q_DECLARE_TYPEINFO(Log4Qt::DailyRollingFileAppender, Q_COMPLEX_TYPE); // Use default + + +#endif // LOG4QT_DAILYROLLINGFILEAPPENDER_H diff --git a/src/log4qt/log4qt/fileappender.cpp b/src/log4qt/log4qt/fileappender.cpp new file mode 100644 index 0000000..265634f --- /dev/null +++ b/src/log4qt/log4qt/fileappender.cpp @@ -0,0 +1,307 @@ +/****************************************************************************** + * + * package: Log4Qt + * file: fileappender.cpp + * created: September 2007 + * author: Martin Heinrich + * + * + * Copyright 2007 Martin Heinrich + * + * 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. + * + ******************************************************************************/ + + + +/****************************************************************************** + * Dependencies + ******************************************************************************/ + + +#include "log4qt/fileappender.h" + +#include +#include +#include +#include +#include +#include +#include "log4qt/layout.h" +#include "log4qt/loggingevent.h" + + + +namespace Log4Qt +{ + + + /************************************************************************** + * Declarations + **************************************************************************/ + + + + /************************************************************************** + * C helper functions + **************************************************************************/ + + + + /************************************************************************** + * Class implementation: FileAppender + **************************************************************************/ + + + FileAppender::FileAppender(QObject *pParent) : + WriterAppender(pParent), + mAppendFile(false), + mBufferedIo(true), + mFileName(), + mpFile(0), + mpTextStream(0) + { + } + + + FileAppender::FileAppender(Layout *pLayout, + const QString &rFileName, + QObject *pParent) : + WriterAppender(pLayout, pParent), + mAppendFile(false), + mBufferedIo(true), + mFileName(rFileName), + mpFile(0), + mpTextStream(0) + { + } + + + FileAppender::FileAppender(Layout *pLayout, + const QString &rFileName, + bool append, + QObject *pParent) : + WriterAppender(pLayout, pParent), + mAppendFile(append), + mBufferedIo(true), + mFileName(rFileName), + mpFile(0), + mpTextStream(0) + { + } + + + FileAppender::FileAppender(Layout *pLayout, + const QString &rFileName, + bool append, + bool buffered, + QObject *pParent) : + WriterAppender(pLayout, pParent), + mAppendFile(append), + mBufferedIo(buffered), + mFileName(rFileName), + mpFile(0), + mpTextStream(0) + { + } + + + FileAppender::~FileAppender() + { + close(); + } + + + void FileAppender::activateOptions() + { + QMutexLocker locker(&mObjectGuard); + + if (mFileName.isEmpty()) + { + LogError e = LOG4QT_QCLASS_ERROR(QT_TR_NOOP("Activation of Appender '%1' that requires file and has no file set"), + APPENDER_ACTIVATE_MISSING_FILE_ERROR); + e << name(); + logger()->error(e); + return; + } + closeFile(); + openFile(); + WriterAppender::activateOptions(); + } + + + void FileAppender::close() + { + QMutexLocker locker(&mObjectGuard); + + if (isClosed()) + return; + + WriterAppender::close(); + closeFile(); + } + + + bool FileAppender::checkEntryConditions() const + { + // Q_ASSERT_X(, "FileAppender::checkEntryConditions()", "Lock must be held by caller") + + if (!mpFile || !mpTextStream) + { + LogError e = LOG4QT_QCLASS_ERROR(QT_TR_NOOP("Use of appender '%1' without open file"), + APPENDER_NO_OPEN_FILE_ERROR); + e << name(); + logger()->error(e); + return false; + } + + return WriterAppender::checkEntryConditions(); + } + + + void FileAppender::closeFile() + { + // Q_ASSERT_X(, "FileAppender::closeFile()", "Lock must be held by caller") + + if (mpFile) + logger()->debug("Closing file '%1' for appender '%2'", mpFile->fileName(), name()); + + setWriter(0); + delete mpTextStream; + mpTextStream = 0; + delete mpFile; + mpFile = 0; + } + + +#ifndef QT_NO_DEBUG_STREAM + QDebug FileAppender::debug(QDebug &rDebug) const + { + QString layout_name; + if (layout()) + layout_name = layout()->name(); + QString codec_name; + if (encoding()) + codec_name = QLatin1String(encoding()->name()); + + rDebug.nospace() << "FileAppender(" + << "name:" << name() << " " + << "appendfile:" << appendFile() << " " + << "bufferedio:" << bufferedIo() << " " + << "encoding:" << codec_name << " " + << "file:" << file() << " " + << "filter:" << firstFilter() << " " + << "immediateflush:" << immediateFlush() << " " + << "isactive:" << isActive() << " " + << "isclosed:" << isClosed() << " " + << "layout:" << layout_name << " " + << "referencecount:" << referenceCount() << " " + << "threshold:" << threshold().toString() << " " + << "writer:" << writer() + << ")"; + return rDebug.space(); + } +#endif // QT_NO_DEBUG_STREAM + + + bool FileAppender::handleIoErrors() const + { + // Q_ASSERT_X(, "FileAppender::handleIoErrors()", "Lock must be held by caller") + + if (mpFile->error() == QFile::NoError) + return false; + + LogError e = LOG4QT_QCLASS_ERROR(QT_TR_NOOP("Unable to write to file '%1' for appender '%2'"), + APPENDER_WRITING_FILE_ERROR); + e << mFileName << name(); + e.addCausingError(LogError(mpFile->errorString(), mpFile->error())); + logger()->error(e); + return true; + } + + + void FileAppender::openFile() + { + Q_ASSERT_X(mpFile == 0 && mpTextStream == 0, "FileAppender::openFile()", "Opening file without closing previous file"); + + QFileInfo file_info(mFileName); + QDir parent_dir = file_info.dir(); + if (!parent_dir.exists()) + { + logger()->trace("Creating missing parent directory for file %1", mFileName); + QString name = parent_dir.dirName(); + parent_dir.cdUp(); + parent_dir.mkdir(name); + } + + + mpFile = new QFile(mFileName); + QFile::OpenMode mode = QIODevice::WriteOnly | QIODevice::Text; + if (mAppendFile) + mode |= QIODevice::Append; + else + mode |= QIODevice::Truncate; + if (!mBufferedIo) + mode |= QIODevice::Unbuffered; + if (!mpFile->open(mode)) + { + LogError e = LOG4QT_QCLASS_ERROR(QT_TR_NOOP("Unable to open file '%1' for appender '%2'"), + APPENDER_OPENING_FILE_ERROR); + e << mFileName << name(); + e.addCausingError(LogError(mpFile->errorString(), mpFile->error())); + logger()->error(e); + return; + } + mpTextStream = new QTextStream(mpFile); + setWriter(mpTextStream); + logger()->debug("Opened file '%1' for appender '%2'", mpFile->fileName(), name()); + } + + + bool FileAppender::removeFile(QFile &rFile) const + { + if (rFile.remove()) + return true; + + LogError e = LOG4QT_QCLASS_ERROR(QT_TR_NOOP("Unable to remove file '%1' for appender '%2'"), + APPENDER_REMOVE_FILE_ERROR); + e << rFile.fileName() << name(); + e.addCausingError(LogError(rFile.errorString(), rFile.error())); + logger()->error(e); + return false; + } + + + bool FileAppender::renameFile(QFile &rFile, + const QString &rFileName) const + { + logger()->debug("Renaming file '%1' to '%2'", rFile.fileName(), rFileName); + if (rFile.rename(rFileName)) + return true; + + LogError e = LOG4QT_QCLASS_ERROR(QT_TR_NOOP("Unable to rename file '%1' to '%2' for appender '%3'"), + APPENDER_RENAMING_FILE_ERROR); + e << rFile.fileName() << rFileName << name(); + e.addCausingError(LogError(rFile.errorString(), rFile.error())); + logger()->error(e); + return false; + } + + + + /************************************************************************** + * Implementation: Operators, Helper + **************************************************************************/ + + +} // namespace Log4Qt diff --git a/src/log4qt/log4qt/fileappender.h b/src/log4qt/log4qt/fileappender.h new file mode 100644 index 0000000..29181ab --- /dev/null +++ b/src/log4qt/log4qt/fileappender.h @@ -0,0 +1,233 @@ +/****************************************************************************** + * + * package: Log4Qt + * file: fileappender.h + * created: September 2007 + * author: Martin Heinrich + * + * + * Copyright 2007 Martin Heinrich + * + * 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. + * + ******************************************************************************/ + +#ifndef LOG4QT_FILEAPPENDER_H +#define LOG4QT_FILEAPPENDER_H + + +/****************************************************************************** + * Dependencies + ******************************************************************************/ + +#include "log4qt/writerappender.h" +#include "ukui-logmacros.h" + +/****************************************************************************** + * Declarations + ******************************************************************************/ + +class QFile; +class QTextStream; + +namespace Log4Qt +{ + + /*! + * \brief The class FileAppender appends log events to a file. + * + * \note All the functions declared in this class are thread-safe. + * + * \note The ownership and lifetime of objects of this class are managed. See + * \ref Ownership "Object ownership" for more details. + */ + class LIBUKUILOG4QT_EXPORT FileAppender : public WriterAppender + { + Q_OBJECT + + /*! + * The property holds, if the output is appended to the file. + * + * The default is false for not appending. + * + * \sa appendFile(), setAppendFile() + */ + Q_PROPERTY(bool appendFile READ appendFile WRITE setAppendFile) + + /*! + * The property holds, if the output is buffered. + * + * The default is true for buffering. + * + * \sa bufferedIo(), setBufferedIo() + */ + Q_PROPERTY(bool bufferedIo READ bufferedIo WRITE setBufferedIo) + + /*! + * The property holds the name of the file. + * + * \sa file(), setFile() + */ + Q_PROPERTY(QString file READ file WRITE setFile) + + public: + FileAppender(QObject *pParent = 0); + FileAppender(Layout *pLayout, + const QString &rFileName, + QObject *pParent = 0); + FileAppender(Layout *pLayout, + const QString &rFileName, + bool append, + QObject *pParent = 0); + FileAppender(Layout *pLayout, + const QString &rFileName, + bool append, + bool buffered, + QObject *pParent = 0); + virtual ~FileAppender(); + private: + FileAppender(const FileAppender &rOther); // Not implemented + FileAppender &operator=(const FileAppender &rOther); // Not implemented + + public: + bool appendFile() const; + QString file() const; + bool bufferedIo() const; + // JAVA: int bufferSize() const; + void setAppendFile(bool append); + void setBufferedIo(bool buffered); + // JAVA: void setBufferSize(int bufferSize); + void setFile(const QString &rFileName); + + virtual void activateOptions(); + virtual void close(); + + protected: + /*! + * Tests if all entry conditions for using append() in this class are met. + * + * If a conditions is not met, an error is logged and the function returns + * false. Otherwise the result of WriterAppender::checkEntryConditions() + * is returned. + * + * The checked conditions are: + * - That a file is set and open (APPENDER_NO_OPEN_FILE_ERROR) + * + * The function is called as part of the checkEntryConditions() chain + * started by AppenderSkeleton::doAppend(). + * + * \sa AppenderSkeleton::doAppend(), AppenderSkeleton::checkEntryConditions() + */ + virtual bool checkEntryConditions() const; + + void closeFile(); + +#ifndef QT_NO_DEBUG_STREAM + /*! + * Writes all object member variables to the given debug stream \a rDebug + * and returns the stream. + * + * + * %FileAppender(name:"FA" appendfile:false bufferedio:true encoding:"" + * file:"/log.txt" filter: 0x0 immediateflush:true isactive:false + * isclosed:false layout:"TTCC" referencecount:2 + * threshold:"NULL" writer:0x0) + * + * \sa QDebug, operator<<(QDebug debug, const LogObject &rLogObject) + */ + virtual QDebug debug(QDebug &rDebug) const; +#endif // QT_NO_DEBUG_STREAM + + /*! + * Checks for file I/O errrors. If an error is found it is logged and the + * function returns true. Otherwise false is returned. + */ + virtual bool handleIoErrors() const; + + /*! + * Opens the file for the appender based on the specified file name and + * mode. A text stream is created and passed on to the super class + * WriterAppender. + * + * If the parent directory of the specified file does not exists, + * it is created. + */ + void openFile(); + + /*! + * Removes the file \a rFile. If the operation is successful, true is + * returned. Otherwise an APPENDER_REMOVE_FILE_ERROR error is logged + * and false is returned. + */ + bool removeFile(QFile &rFile) const; + + /*! + * Renames the file \a rFile to \a rFileName. If the operation is + * successful, true is returned. Otherwise an + * APPENDER_RENAMING_FILE_ERROR error is logged and false is returned. + */ + bool renameFile(QFile &rFile, + const QString &rFileName) const; + + // JAVA: void setQWForFiles(Writer writer); + + private: + volatile bool mAppendFile; + volatile bool mBufferedIo; + QString mFileName; + QFile *mpFile; + QTextStream *mpTextStream; + }; + + + /************************************************************************** + * Operators, Helper + **************************************************************************/ + + + /************************************************************************** + * Inline + **************************************************************************/ + + inline bool FileAppender::appendFile() const + { // QMutexLocker locker(&mObjectGuard); // Read/Write of int is safe + return mAppendFile; } + + inline QString FileAppender::file() const + { QMutexLocker locker(&mObjectGuard); + return mFileName; } + + inline bool FileAppender::bufferedIo() const + { // QMutexLocker locker(&mObjectGuard); // Read/Write of int is safe + return mBufferedIo; } + + inline void FileAppender::setAppendFile(bool append) + { // QMutexLocker locker(&mObjectGuard); // Read/Write of int is safe + mAppendFile = append; } + + inline void FileAppender::setBufferedIo(bool buffered) + { // QMutexLocker locker(&mObjectGuard); // Read/Write of int is safe + mBufferedIo = buffered; } + + inline void FileAppender::setFile(const QString &rFileName) + { QMutexLocker locker(&mObjectGuard); + mFileName = rFileName; } + + +} // namespace Log4Qt + + +// Q_DECLARE_TYPEINFO(Log4Qt::FileAppender, Q_COMPLEX_TYPE); // Use default + + +#endif // LOG4QT_FILEAPPENDER_H diff --git a/src/log4qt/log4qt/helpers/classlogger.cpp b/src/log4qt/log4qt/helpers/classlogger.cpp new file mode 100644 index 0000000..50b6c7f --- /dev/null +++ b/src/log4qt/log4qt/helpers/classlogger.cpp @@ -0,0 +1,100 @@ +/****************************************************************************** + * + * package: Log4Qt + * file: classlogger.cpp + * created: September 2007 + * author: Martin Heinrich + * + * + * changes: Sep 2008, Martin Heinrich: + * - Replaced usage of q_atomic_test_and_set_ptr with + * QAtomicPointer + * + * + * Copyright 2007 - 2008 Martin Heinrich + * + * 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. + * + ******************************************************************************/ + + + +/****************************************************************************** + * Dependencies + ******************************************************************************/ + + +#include "log4qt/helpers/classlogger.h" + +#include +#include "log4qt/logmanager.h" + + +namespace Log4Qt +{ + + + /************************************************************************** + * Declarations + **************************************************************************/ + + + + /************************************************************************** + * C helper functions + **************************************************************************/ + + + + /************************************************************************** + * Class implementation: ClassLogger + **************************************************************************/ + + + ClassLogger::ClassLogger() : + mpLogger(0) + { + } + + + Logger *ClassLogger::logger(const QObject *pObject) + { + Q_ASSERT_X(pObject, "ClassLogger::logger()", "pObject must not be null"); +#if QT_VERSION < QT_VERSION_CHECK(4, 4, 0) + if (!mpLogger) + q_atomic_test_and_set_ptr(&mpLogger, + 0, + LogManager::logger(QLatin1String(pObject->metaObject()->className()))); + return const_cast(mpLogger); +#elif QT_VERSION < QT_VERSION_CHECK(5, 0, 0) + if (!static_cast(mpLogger)) + mpLogger.testAndSetOrdered(0, + LogManager::logger(QLatin1String(pObject->metaObject()->className()))); + return const_cast(static_cast(mpLogger)); +#else + if (!static_cast(mpLogger.loadAcquire())) + mpLogger.testAndSetOrdered(0, + LogManager::logger(QLatin1String(pObject->metaObject()->className()))); + return const_cast(static_cast(mpLogger.loadAcquire())); +#endif + } + + + + /************************************************************************** + * Implementation: Operators, Helper + **************************************************************************/ + + + +} // namespace Log4Qt diff --git a/src/log4qt/log4qt/helpers/classlogger.h b/src/log4qt/log4qt/helpers/classlogger.h new file mode 100644 index 0000000..9e10399 --- /dev/null +++ b/src/log4qt/log4qt/helpers/classlogger.h @@ -0,0 +1,117 @@ +/****************************************************************************** + * + * package: Log4Qt + * file: classlogger.h + * created: September 2007 + * author: Martin Heinrich + * + * + * changes: Sep 2008, Martin Heinrich: + * - Replaced usage of q_atomic_test_and_set_ptr with + * QAtomicPointer + * + * + * Copyright 2007 - 2008 Martin Heinrich + * + * 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. + * + ******************************************************************************/ + +#ifndef LOG4QT_CLASSLOGGER_H +#define LOG4QT_CLASSLOGGER_H + +#include "ukui-logmacros.h" + + +/****************************************************************************** + * Dependencies + ******************************************************************************/ + +#include +#if QT_VERSION >= QT_VERSION_CHECK(4, 4, 0) +# include +# ifndef Q_ATOMIC_POINTER_TEST_AND_SET_IS_ALWAYS_NATIVE +# warning "QAtomicPointer test and set is not native. The class Log4Qt::ClassLogger is not thread-safe." +# endif +#endif + + +/****************************************************************************** + * Declarations + ******************************************************************************/ + +namespace Log4Qt +{ + class Logger; + + /*! + * \brief The class ClassLogger provides logging for a QObject derived + * class. + * + * The class ClassLogger provides a logger for a specified QObject derived + * object. It is used by \ref LOG4QT_DECLARE_QCLASS_LOGGER to implement the + * member functions provided by the macro. + * + * \note All the functions declared in this class are thread-safe. + * + * \sa LOG4QT_DECLARE_QCLASS_LOGGER + */ + class LIBUKUILOG4QT_EXPORT ClassLogger + { + public: + /*! + * Creates a ClassLogger object. + */ + ClassLogger(); + // ~ClassLogger(); // Use compiler default + // ClassLogger(const ClassLogger &rOther); // Use compiler default + // ClassLogger &operator=(const ClassLogger &rOther); // Use compiler default + + /*! + * Returns a pointer to a Logger named after the class of the object + * \a pObject. + * + * On the first invocation the Logger is requested by a call to + * LogManager::logger(const char *pName). The pointer is stored to be + * returned on subsequent invocations. + * + * \sa LogManager::logger(const char *pName) + */ + Logger *logger(const QObject *pObject); + + private: +#if QT_VERSION < QT_VERSION_CHECK(4, 4, 0) + volatile Logger *mpLogger; +#else + mutable QAtomicPointer mpLogger; +#endif + }; + + + /****************************************************************************** + * Operators, Helper + ******************************************************************************/ + + + /************************************************************************** + * Inline + **************************************************************************/ + + +} // namespace Log4Qt + + +// Q_DECLARE_TYPEinfo(Log4Qt::ClassLogger, Q_COMPLEX_TYPE); // Use default + + +#endif // LOG4QT_CLASSLOGGER_H diff --git a/src/log4qt/log4qt/helpers/configuratorhelper.cpp b/src/log4qt/log4qt/helpers/configuratorhelper.cpp new file mode 100644 index 0000000..3b34f40 --- /dev/null +++ b/src/log4qt/log4qt/helpers/configuratorhelper.cpp @@ -0,0 +1,136 @@ +/****************************************************************************** + * + * package: Log4Qt + * file: configuratorhelper.cpp + * created: September 2007 + * author: Martin Heinrich + * + * + * Copyright 2007 Martin Heinrich + * + * 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. + * + ******************************************************************************/ + + + +/****************************************************************************** + * Dependencies + ******************************************************************************/ + + +#include "log4qt/helpers/configuratorhelper.h" + +#include +#include +#include "log4qt/helpers/initialisationhelper.h" + + + +namespace Log4Qt +{ + + + /************************************************************************** + * Declarations + **************************************************************************/ + + + + /************************************************************************** + * C helper functions + **************************************************************************/ + + + + /************************************************************************** + * Class implementation: ConfiguratorHelper + **************************************************************************/ + + + ConfiguratorHelper::ConfiguratorHelper() : + mObjectGuard(), + mConfigurationFile(), + mpConfigureFunc(0), + mpConfigurationFileWatch(0), + mConfigureError() + { + } + + + ConfiguratorHelper::~ConfiguratorHelper() + { + delete mpConfigurationFileWatch; + } + + + LOG4QT_IMPLEMENT_INSTANCE(ConfiguratorHelper) + + + void ConfiguratorHelper::doConfigurationFileChanged(const QString &rFileName) + { + QMutexLocker locker(&mObjectGuard); + + if (!mpConfigureFunc) + return; + mpConfigureFunc(rFileName); + // Shall we hold the lock while emitting the signal? + emit configurationFileChanged(rFileName, mConfigureError.count() > 0); + } + + + + void ConfiguratorHelper::doSetConfigurationFile(const QString &rFileName, + ConfigureFunc pConfigureFunc) + { + QMutexLocker locker(&mObjectGuard); + + mConfigurationFile.clear(); + mpConfigureFunc = 0; + delete mpConfigurationFileWatch; + if (rFileName.isEmpty()) + return; + + mConfigurationFile = rFileName; + mpConfigureFunc = pConfigureFunc; + mpConfigurationFileWatch = new QFileSystemWatcher(); + mpConfigurationFileWatch->addPath(rFileName); + connect(mpConfigurationFileWatch, + SIGNAL(fileChanged(const QString &)), + SLOT(configurationFileChanged(const QString &))); + } + + + + /************************************************************************** + * Implementation: Operators, Helper + **************************************************************************/ + + +#ifndef QT_NO_DEBUG_STREAM + QDebug operator<<(QDebug debug, + const ConfiguratorHelper &rConfiguratorHelper) + { + debug.nospace() << "ConfiguratorHelper(" + << "configurationfile:" << ConfiguratorHelper::configurationFile() + << "configurefunc:" << rConfiguratorHelper.mpConfigureFunc + << "filesystemwatcher:" << rConfiguratorHelper.mpConfigurationFileWatch + << ")"; + return debug.space(); + } +#endif // QT_NO_DEBUG_STREAM + + + +} // namespace Log4Qt + diff --git a/src/log4qt/log4qt/helpers/configuratorhelper.h b/src/log4qt/log4qt/helpers/configuratorhelper.h new file mode 100644 index 0000000..fd55252 --- /dev/null +++ b/src/log4qt/log4qt/helpers/configuratorhelper.h @@ -0,0 +1,211 @@ +/****************************************************************************** + * + * package: Log4Qt + * file: configuratorhelper.h + * created: September 2007 + * author: Martin Heinrich + * + * + * Copyright 2007 Martin Heinrich + * + * 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. + * + ******************************************************************************/ + +#ifndef LOG4QT_HELPERS_CONFIGURATORHELPER_H +#define LOG4QT_HELPERS_CONFIGURATORHELPER_H + + +/****************************************************************************** + * Dependencies + ******************************************************************************/ + +#include + +#include +#include +#include "log4qt/loggingevent.h" +#include "ukui-logmacros.h" + + +/****************************************************************************** + * Declarations + ******************************************************************************/ + +class QFileSystemWatcher; + + +namespace Log4Qt +{ + + /*! + * \brief The class ConfiguratorHelper provides a confiuration file watch + * and last error for configurator classes. + * + * A configuration file can be set using setConfigurationFile(). The file + * is watched for changes. If a change occurs the configuration is reloaded + * and the ConfigurationFileChanged() signal is emitted. Error information + * for the last call to a configure function or the last configuration file + * change can be accessed using configureError(). + * + * \note All the functions declared in this class are thread-safe. + */ + class LIBUKUILOG4QT_EXPORT ConfiguratorHelper : public QObject + { + Q_OBJECT + + public: + /*! + * Prototype for a configure callback function. The function is called + * when then configuration file is changed and takes the + * configuration file as a parameter. + * + * \sa setConfigurationFile(), + * PropertyConfigurator::configure(const QString &) + */ + typedef bool (*ConfigureFunc)(const QString &rFileName); + + private: + ConfiguratorHelper(); + ConfiguratorHelper(const ConfiguratorHelper &rOther); // Not implemented + virtual ~ConfiguratorHelper(); + ConfiguratorHelper &operator=(const ConfiguratorHelper &rOther); // Not implemented + + public: + + /*! + * Returns the error information for the last configuration operation + * that took place. The configuration operation could be the result of + * a call to one of the configure methods or through a change + * to the configuration file. + * + * \sa setConfigureError(), PropertyConfigurator::configure(), + * setConfigurationFile() + */ + static QList configureError(); + + /*! + * Returns the current configuration file. + * + * \sa setConfigurationFile() + */ + static QString configurationFile(); + + /*! + * Returns the ConfiguratorHelper instance. + */ + static ConfiguratorHelper *instance(); + + /*! + * Sets the configuration error information for the last configuration + * operation. + * + * \sa configureError() + */ + static void setConfigureError(const QList &rConfigureError); + + /*! + * Sets the configuration file to \a rFileName. The file is watched for + * changes. On a file change the function \a pConfigureFunc will be called + * and the signal configurationFileChange() will be emitted. + * + * Setting the configuration file to an empty string stops the file watch. + * + * \sa configurationFile(), PropertyConfigurator::configureAndWatch(), + * configureError() + */ + static void setConfigurationFile(const QString &rFileName = QString(), + ConfigureFunc pConfigureFunc = 0); + + signals: + /*! + * The signal is emitted after a change to the file \a rFileName + * was processed. If an error occured during the configuration, the + * flag \a error will be true and error information is available + * over configureError(). + */ + void configurationFileChanged(const QString &rFileName, + bool error); + + private slots: + void doConfigurationFileChanged(const QString &rFileName); + + private: + void doSetConfigurationFile(const QString &rFileName, + ConfigureFunc pConfigureFunc); + + private: + mutable QMutex mObjectGuard; + QString mConfigurationFile; + ConfigureFunc mpConfigureFunc; + QFileSystemWatcher *mpConfigurationFileWatch; + QList mConfigureError; + +#ifndef QT_NO_DEBUG_STREAM + // Needs to be friend to access details + friend QDebug operator<<(QDebug debug, + const ConfiguratorHelper &rConfiguratorHelper); +#endif // QT_NO_DEBUG_STREAM + }; + + + /************************************************************************** + * Operators, Helper + **************************************************************************/ + +#ifndef QT_NO_DEBUG_STREAM + /*! + * \relates ConfiguratorHelper + * + * Writes all object member variables to the given debug stream \a rDebug and + * returns the stream. + * + * + * %ConfiguratorHelper(configurationfile: "" configurefunc: false + * filesystemwatcher: QObject(0x0) ) + * + * \sa QDebug, ConfiguratorHelper::logManager() + */ + QDebug operator<<(QDebug debug, + const ConfiguratorHelper &rConfiguratorHelper); +#endif // QT_NO_DEBUG_STREAM + + + + /************************************************************************** + * Inline + **************************************************************************/ + + inline QList ConfiguratorHelper::configureError() + { QMutexLocker locker(&instance()->mObjectGuard); + return instance()->mConfigureError; } + + inline QString ConfiguratorHelper::configurationFile() + { QMutexLocker locker(&instance()->mObjectGuard); + return instance()->mConfigurationFile; } + + inline void ConfiguratorHelper::setConfigureError(const QList &rConfigureError) + { QMutexLocker locker(&instance()->mObjectGuard); + instance()->mConfigureError = rConfigureError; } + + inline void ConfiguratorHelper::setConfigurationFile(const QString &rFileName, + ConfigureFunc pConfigureFunc) + { instance()->doSetConfigurationFile(rFileName, pConfigureFunc); } + +} // namespace Log4Qt + + +// Q_DECLARE_TYPEINFO(Log4Qt::ConfiguratorHelper, Q_COMPLEX_TYPE); // use default + + +#endif // LOG4QT_HELPERS_CONFIGURATORHELPER_H diff --git a/src/log4qt/log4qt/helpers/datetime.cpp b/src/log4qt/log4qt/helpers/datetime.cpp new file mode 100644 index 0000000..1fb7d87 --- /dev/null +++ b/src/log4qt/log4qt/helpers/datetime.cpp @@ -0,0 +1,326 @@ +/****************************************************************************** + * + * package: Log4Qt + * file: datetime.cpp + * created: September 2007 + * author: Martin Heinrich + * + * + * Copyright 2007 Martin Heinrich + * + * 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. + * + ******************************************************************************/ + + + +/****************************************************************************** + * Dependencies + ******************************************************************************/ + + +#include "log4qt/helpers/datetime.h" + +#include +#include "log4qt/helpers/initialisationhelper.h" + + + +namespace Log4Qt +{ + + + /************************************************************************** + *Declarations + **************************************************************************/ + + + + /************************************************************************** + * C helper functions + **************************************************************************/ + + + + /************************************************************************** + * Class implementation: DateTime + **************************************************************************/ + + + QString DateTime::toString(const QString &rFormat) const + { + QString format(rFormat); + + if (format.isEmpty()) + return QString(); + if (!isValid()) + return QString(); + if (format == QLatin1String("NONE")) + return QString(); + + if (format == QLatin1String("TIME_RELATIVE")) + return QString::number(toMilliSeconds() - InitialisationHelper::startTime()); + + if (format == QLatin1String("ISO8601")) + format = QLatin1String("yyyy-MM-dd hh:mm:ss.zzz"); + if (format == QLatin1String("TIME_ABSOLUTE")) + format = QLatin1String("HH:mm:ss.zzz"); + if (format == QLatin1String("DATE")) + format = QLatin1String("dd MMM YYYY HH:mm:ss.zzzz"); + + return formatDateTime(format); + } + + + QString DateTime::formatDateTime(const QString &rFormat) const + { + if (rFormat.isEmpty()) + return QString(); + if (!isValid()) + return QString(); + + const QLatin1Char null('0'); + const QLatin1Char quote('\''); + const QString tokens = QLatin1String("\'dMyhHmszAPapw"); + const bool am_pm = hasAMPM(rFormat); + + QString result; + QString token; + QChar expected = null; + + QChar c; + int i; + for (i = 0; i < rFormat.length(); i++) + { + c = rFormat.at(i); + + // Handle literal text + if (expected == quote) + { + if (c == quote) + { + Q_ASSERT_X(i > 0, "DateTime::toString()", "Found quote with status quote at i = 0"); + if (i > 0 && rFormat.at(i - 1) == quote) + // Second of two quotes + result += quote; + expected = null; + } + else + // Next literal character + result += c; + } + else if (c == expected) + { + // Extend token + token += c; + } + else + { + // Close last token + result += formatToken(token, am_pm); + token.clear(); + expected = null; + + // Test for valid character + if (tokens.indexOf(c) >= 0) + { + if (c == QLatin1Char('a')) + expected = QLatin1Char('p'); + else if (c == QLatin1Char('A')) + expected = QLatin1Char('P'); + else if (c.toLower() == QLatin1Char('p')) + expected = null; + else + expected = c; + if (c != quote) + token += c; + } else + result += c; + } + } + + result += formatToken(token, am_pm); + return result; + } + + + QString DateTime::formatToken(const QString &rToken, bool am_pm) const + { + if (rToken.isEmpty()) + return QString(); + + const QChar c = rToken.at(0); + QString result; + int used = 0; + + // Qt data format strings + if (rToken.startsWith(QLatin1String("dddd"))) + { + result = QDate::longDayName(date().dayOfWeek()); + used = 4; + } + else if (rToken.startsWith(QLatin1String("ddd"))) + { + result = QDate::shortDayName(date().dayOfWeek()); + used = 3; + } + else if (rToken.startsWith(QLatin1String("dd"))) + { + result = QString::number(date().day()).rightJustified(2, QLatin1Char('0'), true); + used = 2; + } + else if (c == QLatin1Char('d')) + { + result = QString::number(date().day()); + used = 1; + } + else if (rToken.startsWith(QLatin1String("MMMM"))) + { + result = QDate::longMonthName(date().month()); + used = 4; + } + else if (rToken.startsWith(QLatin1String("MMM"))) + { + result = QDate::shortMonthName(date().month()); + used = 3; + } + else if (rToken.startsWith(QLatin1String("MM"))) + { + result = QString::number(date().month()).rightJustified(2, QLatin1Char('0'), true); + used = 2; + } + else if (c == QLatin1Char('M')) + { + result = QString::number(date().month()); + used = 1; + } + else if (rToken.startsWith(QLatin1String("yyyy"))) + { + result = QString::number(date().year()); + used = 4; + } + else if (rToken.startsWith(QLatin1String("yy"))) + { + result = QString::number(date().year() % 100).rightJustified(2, QLatin1Char('0'), true); + used = 2; + } + + // Qt time format strings + else if (rToken.startsWith(QLatin1String("hh")) || rToken.startsWith(QLatin1String("HH"))) + { + int hour = time().hour(); + if (am_pm && c == QLatin1Char('h') && hour > 12) + hour -= 12; + result = QString::number(hour).rightJustified(2, QLatin1Char('0'), true); + used = 2; + } + else if (c == QLatin1Char('h') || c == QLatin1Char('H')) + { + int hour = time().hour(); + if (am_pm && c == QLatin1Char('h') && hour > 12) + hour -= 12; + result = QString::number(hour); + used = 2; + } + else if (rToken.startsWith(QLatin1String("mm"))) + { + result = QString::number(time().minute()).rightJustified(2, QLatin1Char('0'), true); + used = 2; + } + else if (c == (QLatin1Char('m'))) + { + result = QString::number(time().minute()); + used = 1; + } + else if (rToken.startsWith(QLatin1String("ss"))) + { + result = QString::number(time().second()).rightJustified(2, QLatin1Char('0'), true); + used = 2; + } + else if (c == QLatin1Char('s')) + { + result = QString::number(time().second()); + used = 1; + } + else if (rToken.startsWith(QLatin1String("zzz"))) + { + result = QString::number(time().msec()).rightJustified(3, QLatin1Char('0'), true); + used = 3; + } + else if (c == QLatin1Char('z')) + { + result = QString::number(time().msec()); + used = 1; + } + else if (c.toLower() == QLatin1Char('a')) + { + bool is_lower = c == QLatin1Char('a'); + if (time().hour() < 12) + result = QLatin1String("AM"); + else + result = QLatin1String("PM"); + if (is_lower) + result = result.toLower(); + if (rToken.size() > 1 && + ((is_lower && rToken.at(1) == QLatin1Char('p')) || + (!is_lower && rToken.at(1) == QLatin1Char('P'))) + ) + used = 2; + else + used = 1; + } + + // Extension for week number + else if (rToken.startsWith(QLatin1String("ww"))) + { + result = QString::number(date().weekNumber()).rightJustified(2, QLatin1Char('0'), true); + used = 2; + } + else if (c == QLatin1Char('w')) + { + result = QString::number(date().weekNumber()); + used = 1; + } + + if (used) + return result + formatToken(rToken.mid(used), am_pm); + else + return result; + } + + + bool DateTime::hasAMPM(const QString &rToken) + { + bool in_literal = false; + QChar c; + int i; + for (i = 0; i < rToken.length(); i++) + { + c = rToken.at(i); + if (c == QLatin1Char('\'')) + in_literal = !in_literal; + else if (!in_literal && c.toLower() == QLatin1Char('a')) + return true; + } + return false; + } + + + + /************************************************************************** + * Implementation: Operators, Helper + **************************************************************************/ + + + +} // namespace Log4Qt diff --git a/src/log4qt/log4qt/helpers/datetime.h b/src/log4qt/log4qt/helpers/datetime.h new file mode 100644 index 0000000..e9c79ce --- /dev/null +++ b/src/log4qt/log4qt/helpers/datetime.h @@ -0,0 +1,213 @@ +/****************************************************************************** + * + * package: Log4Qt + * file: datetime.h + * created: September 2007 + * author: Martin Heinrich + * + * + * changes: Sep 2008, Martin Heinrich: + * - Resolved compilation problem with Microsoft Visual Studio 2005 + * + * + * Copyright 2007 - 2008 Martin Heinrich + * + * 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. + * + ******************************************************************************/ + +#ifndef LOG4QT_HELPERS_DATETIME_H +#define LOG4QT_HELPERS_DATETIME_H + + +/****************************************************************************** + * Dependencies + ******************************************************************************/ + +#include +#include "ukui-logmacros.h" + + +/****************************************************************************** + * Declarations + ******************************************************************************/ + + +namespace Log4Qt +{ + + /*! + * \brief The class DateTime provides extended functionality for QDateTime. + * + * The class DateTime implements additional formatting options for + * toString() and provides conversion functions from and to milliseconds. + */ + class LIBUKUILOG4QT_EXPORT DateTime : public QDateTime + { + public: + /*! + * Constructs a null date time. + * + * \sa QDateTime::QDateTime() + */ + DateTime(); + + // DateTime(const DateTime &rOther); // Use compiler default + + /*! + * Constructs a copy of another QDateTime. + * + * \sa QDateTime::QDateTime(const QDateTime &rOther) + */ + DateTime(const QDateTime &rOther); + + /*! + * Constructs a datetime with the given \a rDate and \a rTime, using + * the time specification defined by \a timeSpec. + * + * \sa QDateTime::QDateTime(const QDate &rDate, const QTime &rTime, + * Qt::TimeSpec timeSpec = Qt::LocalTime) + */ + DateTime(const QDate &rDate, + const QTime &rTime, + Qt::TimeSpec timeSpec = Qt::LocalTime); + + // virtual ~DateTime(); // Use compiler default + + /*! + * Assigns \a rOther to this DateTime and returns a reference to it. + */ + DateTime &operator=(const DateTime &rOther); + + /*! + * Returns the datetime as the number of milliseconds that have passed + * since 1970-01-01T00:00:00,000, Coordinated Universal Time (Qt::UTC). + * + * \sa QDateTime::toTime_t() + */ + qint64 toMilliSeconds() const; + + /*! + * Returns the datetime as a string. The \a rFormat parameter + * determines the format of the result string. + * + * In addition to the expressions of QDateTime::toString(const QString + * &rFormat) the following expression can be used. + * + * + * + * + * + * + * + * + * + * + * + * + *
Expression Output
w the week of the year as number without a leading zero (1 to 53)
ww the week of the year as number with a leading zero (01 to 53)
+ * + * Alternatively the \a rFormat parameter can specify one of the + * following strings. + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + *
String Format
TIME_ABSOLUTE uses the format HH:mm:ss.zzz
DATE uses the format dd MMM YYYY HH:mm:ss.zzzz
ISO8601 uses the format yyyy-MM-dd hh:mm:ss.zzz
NONE uses an empty string as format
TIME_RELATIVE returns the milliseconds since start of the program
+ * + * \sa QDateTime::toString(const QString &rFormat) + */ + QString toString(const QString &rFormat) const; + + /*! + * Returns the current datetime, as reported by the system clock, in + * the local time zone. + * + * \sa QDateTime::currentDateTime() + */ + static DateTime currentDateTime(); + + /*! + * Returns a datetime whose date and time are the number of + * milliseconds that have passed since 1970-01-01T00:00:00, + * Coordinated Universal Time (Qt::UTC). + * + * \sa QDateTime::fromTime_t(uint seconds) + */ + static DateTime fromMilliSeconds(qint64 milliSeconds); + + private: + QString formatDateTime(const QString &rFormat) const; + QString formatToken(const QString &rToken, bool am_pm) const; + static bool hasAMPM(const QString &rFormat); + }; + + + /************************************************************************** + * Operators, Helper + **************************************************************************/ + + + /************************************************************************** + * Inline + **************************************************************************/ + + inline DateTime::DateTime() : QDateTime() + {} + + inline DateTime::DateTime(const QDateTime &rOther) : QDateTime(rOther) + {} + + inline DateTime::DateTime(const QDate &rDate, + const QTime &rTime, + Qt::TimeSpec timeSpec) : + QDateTime(rDate, rTime, timeSpec) + {} + + inline DateTime &DateTime::operator=(const DateTime &rOther) + { QDateTime::operator=(rOther); return *this; } + + inline qint64 DateTime::toMilliSeconds() const + { return (qint64)1000 * toTime_t() + time().msec(); } + + inline DateTime DateTime::currentDateTime() + { return DateTime(QDateTime::currentDateTime()); } + + inline DateTime DateTime::fromMilliSeconds(qint64 milliSeconds) + { return DateTime(QDateTime::fromTime_t(milliSeconds / 1000).addMSecs(milliSeconds % 1000)); } + + +} // namespace Log4Qt + + +Q_DECLARE_TYPEINFO(Log4Qt::DateTime, Q_MOVABLE_TYPE); + + +#endif // LOG4QT_HELPERS_DATETIME_H diff --git a/src/log4qt/log4qt/helpers/factory.cpp b/src/log4qt/log4qt/helpers/factory.cpp new file mode 100644 index 0000000..bf2f449 --- /dev/null +++ b/src/log4qt/log4qt/helpers/factory.cpp @@ -0,0 +1,459 @@ +/****************************************************************************** + * + * package: Log4Qt + * file: factory.cpp + * created: September 2007 + * author: Martin Heinrich + * + * + * Copyright 2007 Martin Heinrich + * + * 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. + * + ******************************************************************************/ + + + +/****************************************************************************** + * Dependencies + ******************************************************************************/ + + +#include "log4qt/helpers/factory.h" + +#include +#include +#include +#include "log4qt/consoleappender.h" +#include "log4qt/dailyrollingfileappender.h" +#include "log4qt/fileappender.h" +#include "log4qt/helpers/logerror.h" +#include "log4qt/helpers/initialisationhelper.h" +#include "log4qt/helpers/optionconverter.h" +#include "log4qt/patternlayout.h" +#include "log4qt/rollingfileappender.h" +#include "log4qt/simplelayout.h" +#include "log4qt/ttcclayout.h" +#include "log4qt/varia/debugappender.h" +#include "log4qt/varia/denyallfilter.h" +#include "log4qt/varia/levelmatchfilter.h" +#include "log4qt/varia/levelrangefilter.h" +#include "log4qt/varia/listappender.h" +#include "log4qt/varia/nullappender.h" +#include "log4qt/varia/stringmatchfilter.h" + + + +namespace Log4Qt +{ + + + /************************************************************************** + * Declarations + **************************************************************************/ + + + + /************************************************************************** + * C helper functions + **************************************************************************/ + + + LOG4QT_DECLARE_STATIC_LOGGER(logger, Log4Qt::Factory) + + + // Appenders + + Appender *console_file_appender() + { return new ConsoleAppender; } + + Appender *create_daily_rolling_file_appender() + { return new DailyRollingFileAppender; } + + Appender *create_debug_appender() + { return new DebugAppender; } + + Appender *create_file_appender() + { return new FileAppender; } + + Appender *create_list_appender() + { return new ListAppender; } + + Appender *create_null_appender() + { return new NullAppender; } + + Appender *create_rolling_file_appender() + { return new RollingFileAppender; } + + + // Filters + + Filter *create_deny_all_filter() + { return new DenyAllFilter; } + + Filter *create_level_match_filter() + { return new LevelMatchFilter; } + + Filter *create_level_range_filter() + { return new LevelRangeFilter; } + + Filter *create_string_match_filter() + { return new StringMatchFilter; } + + + // Layouts + + Layout *create_pattern_layout() + { return new PatternLayout; } + + Layout *create_simple_layout() + { return new SimpleLayout; } + + Layout *create_ttcc_layout() + { return new TTCCLayout; } + + + + /************************************************************************** + * Class implementation: Factory + **************************************************************************/ + + + Factory::Factory() : + mObjectGuard(), + mAppenderRegistry(), + mFilterRegistry(), + mLayoutRegistry() + { + registerDefaultAppenders(); + registerDefaultFilters(); + registerDefaultLayouts(); + } + + + LOG4QT_IMPLEMENT_INSTANCE(Factory) + + + Appender *Factory::doCreateAppender(const QString &rAppenderClassName) + { + QMutexLocker locker(&mObjectGuard); + + if (!mAppenderRegistry.contains(rAppenderClassName)) + { + logger()->warn("Request for the creation of Appender with class '%1', which is not registered", rAppenderClassName); + return 0; + } + return mAppenderRegistry.value(rAppenderClassName)(); + } + + + Filter *Factory::doCreateFilter(const QString &rFilterClassName) + { + QMutexLocker locker(&mObjectGuard); + + if (!mFilterRegistry.contains(rFilterClassName)) + { + logger()->warn("Request for the creation of Filter with class '%1', which is not registered", rFilterClassName); + return 0; + } + return mFilterRegistry.value(rFilterClassName)(); + } + + + Layout *Factory::doCreateLayout(const QString &rLayoutClassName) + { + QMutexLocker locker(&mObjectGuard); + + if (!mLayoutRegistry.contains(rLayoutClassName)) + { + logger()->warn("Request for the creation of Layout with class '%1', which is not registered", rLayoutClassName); + return 0; + } + return mLayoutRegistry.value(rLayoutClassName)(); + } + + + void Factory::doRegisterAppender(const QString &rAppenderClassName, + AppenderFactoryFunc pAppenderFactoryFunc) + { + QMutexLocker locker(&mObjectGuard); + + if(rAppenderClassName.isEmpty()) + { + logger()->warn("Registering Appender factory function with empty class name"); + return; + } + mAppenderRegistry.insert(rAppenderClassName, pAppenderFactoryFunc); + } + + + void Factory::doRegisterFilter(const QString &rFilterClassName, + FilterFactoryFunc pFilterFactoryFunc) + { + QMutexLocker locker(&mObjectGuard); + + if(rFilterClassName.isEmpty()) + { + logger()->warn("Registering Filter factory function with empty class name"); + return; + } + mFilterRegistry.insert(rFilterClassName, pFilterFactoryFunc); + } + + + void Factory::doRegisterLayout(const QString &rLayoutClassName, + LayoutFactoryFunc pLayoutFactoryFunc) + { + QMutexLocker locker(&mObjectGuard); + + if(rLayoutClassName.isEmpty()) + { + logger()->warn("Registering Layout factory function with empty class name"); + return; + } + mLayoutRegistry.insert(rLayoutClassName, pLayoutFactoryFunc); + } + + + void Factory::doSetObjectProperty(QObject *pObject, + const QString &rProperty, + const QString &rValue) + { + // - Validate property + // - Get correct property name from meta object + // - Find specific property setter + // - If no specfifc propery setter can be found, + // find general property setter + // - Call property setter + + QMetaProperty meta_property; + if (!validateObjectProperty(meta_property, rProperty, pObject)) + return; + + QString property = QLatin1String(meta_property.name()); + QString type = QLatin1String(meta_property.typeName()); + logger()->debug("Setting property '%1' on object of class '%2' to value '%3'", + property, + QLatin1String(pObject->metaObject()->className()), + rValue); + + QVariant value; + bool ok = true; + if (type == QLatin1String("bool")) + value = OptionConverter::toBoolean(rValue, &ok); + else if (type == QLatin1String("int")) + value = OptionConverter::toInt(rValue, &ok); + else if (type == QLatin1String("qint64") || type == QLatin1String("qlonglong")) + value = OptionConverter::toQInt64(rValue, &ok); + else if (type == QLatin1String("Log4Qt::Level")) + value = QVariant::fromValue(OptionConverter::toLevel(rValue, &ok)); + else if (type == QLatin1String("QString")) + value = rValue; + else + { + LogError e = LOG4QT_ERROR(QT_TR_NOOP("Cannot convert to type '%1' for property '%2' on object of class '%3'"), + CONFIGURATOR_UNKNOWN_TYPE_ERROR, + "Log4Qt::Factory"); + e << type + << property + << QString::fromLatin1(pObject->metaObject()->className()); + logger()->error(e); + return; + } + if (!ok) + return; + + // Everything is checked and the type is the one of the property. + // Write should never return false + if (!meta_property.write(pObject, value)) + logger()->warn("Unxpected error result from QMetaProperty.write()"); + } + + + void Factory::doUnregisterAppender(const QString &rAppenderClassName) + { + QMutexLocker locker(&mObjectGuard); + + if (!mAppenderRegistry.contains(rAppenderClassName)) + { + logger()->warn("Request to unregister not registered Appender factory function for class '%1'", rAppenderClassName); + return; + } + mAppenderRegistry.remove(rAppenderClassName); + } + + + void Factory::doUnregisterFilter(const QString &rFilterClassName) + { + QMutexLocker locker(&mObjectGuard); + + if (!mFilterRegistry.contains(rFilterClassName)) + { + logger()->warn("Request to unregister not registered Filter factory function for class '%1'", rFilterClassName); + return; + } + mFilterRegistry.remove(rFilterClassName); + } + + + void Factory::doUnregisterLayout(const QString &rLayoutClassName) + { + QMutexLocker locker(&mObjectGuard); + + if (!mLayoutRegistry.contains(rLayoutClassName)) + { + logger()->warn("Request to unregister not registered Layout factory function for class '%1'", rLayoutClassName); + return; + } + mLayoutRegistry.remove(rLayoutClassName); + } + + + void Factory::registerDefaultAppenders() + { + mAppenderRegistry.insert(QLatin1String("org.apache.log4j.ConsoleAppender"), console_file_appender); + mAppenderRegistry.insert(QLatin1String("Log4Qt::ConsoleAppender"), console_file_appender); + mAppenderRegistry.insert(QLatin1String("org.apache.log4j.DailyRollingFileAppender"), create_daily_rolling_file_appender); + mAppenderRegistry.insert(QLatin1String("Log4Qt::DailyRollingFileAppender"), create_daily_rolling_file_appender); + mAppenderRegistry.insert(QLatin1String("org.apache.log4j.varia.DebugAppender"), create_debug_appender); + mAppenderRegistry.insert(QLatin1String("Log4Qt::DebugAppender"), create_debug_appender); + mAppenderRegistry.insert(QLatin1String("org.apache.log4j.FileAppender"), create_file_appender); + mAppenderRegistry.insert(QLatin1String("Log4Qt::FileAppender"), create_file_appender); + mAppenderRegistry.insert(QLatin1String("org.apache.log4j.varia.ListAppender"), create_list_appender); + mAppenderRegistry.insert(QLatin1String("Log4Qt::ListAppender"), create_list_appender); + mAppenderRegistry.insert(QLatin1String("org.apache.log4j.varia.NullAppender"), create_null_appender); + mAppenderRegistry.insert(QLatin1String("Log4Qt::NullAppender"), create_null_appender); + mAppenderRegistry.insert(QLatin1String("org.apache.log4j.RollingFileAppender"), create_rolling_file_appender); + mAppenderRegistry.insert(QLatin1String("Log4Qt::RollingFileAppender"), create_rolling_file_appender); + } + + + void Factory::registerDefaultFilters() + { + mFilterRegistry.insert(QLatin1String("org.apache.log4j.varia.DenyAllFilter"), create_deny_all_filter); + mFilterRegistry.insert(QLatin1String("Log4Qt::DenyAllFilter"), create_deny_all_filter); + mFilterRegistry.insert(QLatin1String("org.apache.log4j.varia.LevelMatchFilter"), create_level_match_filter); + mFilterRegistry.insert(QLatin1String("Log4Qt::LevelMatchFilter"), create_level_match_filter); + mFilterRegistry.insert(QLatin1String("org.apache.log4j.varia.LevelRangeFilter"), create_level_range_filter); + mFilterRegistry.insert(QLatin1String("Log4Qt::LevelRangeFilter"), create_level_range_filter); + mFilterRegistry.insert(QLatin1String("org.apache.log4j.varia.StringMatchFilter"), create_string_match_filter); + mFilterRegistry.insert(QLatin1String("Log4Qt::StringMatchFilter"), create_string_match_filter); + } + + + void Factory::registerDefaultLayouts() + { + mLayoutRegistry.insert(QLatin1String("org.apache.log4j.PatternLayout"), create_pattern_layout); + mLayoutRegistry.insert(QLatin1String("Log4Qt::PatternLayout"), create_pattern_layout); + mLayoutRegistry.insert(QLatin1String("org.apache.log4j.SimpleLayout"), create_simple_layout); + mLayoutRegistry.insert(QLatin1String("Log4Qt::SimpleLayout"), create_simple_layout); + mLayoutRegistry.insert(QLatin1String("org.apache.log4j.TTCCLayout"), create_ttcc_layout); + mLayoutRegistry.insert(QLatin1String("Log4Qt::TTCCLayout"), create_ttcc_layout); + } + + + bool Factory::validateObjectProperty(QMetaProperty &rMetaProperty, + const QString &rProperty, + QObject *pObject) + { + // Validate: + // - No null object pointer + // - No empty property name + // - Property exists on the object (QT or Java name) + // - Property is readable + // - Property is writable + + const char *p_context = "Log4Qt::Factory"; + LogError e = LOG4QT_ERROR(QT_TR_NOOP("Unable to set property value on object"), + CONFIGURATOR_PROPERTY_ERROR, + p_context); + + if (!pObject) + { + LogError ce = LOG4QT_ERROR(QT_TR_NOOP("Invalid null object pointer"), + 0, + p_context); + e.addCausingError(ce); + logger()->error(e); + return false; + } + if (rProperty.isEmpty()) + { + LogError ce = LOG4QT_ERROR(QT_TR_NOOP("Invalid empty property name"), + 0, + p_context); + e.addCausingError(ce); + logger()->error(e); + return false; + } + const QMetaObject *p_meta_object = pObject->metaObject(); + QString property = rProperty; + int i = p_meta_object->indexOfProperty(property.toLatin1()); + if (i < 0) + { + // Try name with lower case first character. Java properties names + // start upper case + property[0] = property[0].toLower(); + i = p_meta_object->indexOfProperty(property.toLatin1()); + if (i < 0) + { + LogError ce = LOG4QT_ERROR(QT_TR_NOOP("Property '%1' does not exist in class '%2'"), + 0, + p_context); + ce << property + << QString::fromLatin1(pObject->metaObject()->className()); + e.addCausingError(ce); + logger()->error(e); + return false; + } + } + rMetaProperty = p_meta_object->property(i); + if (!rMetaProperty.isWritable()) + { + LogError ce = LOG4QT_ERROR(QT_TR_NOOP("Property '%1' is not writable in class '%2'"), + 0, + p_context); + ce << property + << QString::fromLatin1(pObject->metaObject()->className()); + e.addCausingError(ce); + logger()->error(e); + return false; + } + + return true; + } + + + + /************************************************************************** + * Implementation: Operators, Helper + **************************************************************************/ + + +#ifndef QT_NO_DEBUG_STREAM + QDebug operator<<(QDebug debug, + const Factory &rFactory) + { + debug.nospace() << "Factory(" + << "appenderfactories:" << rFactory.registeredAppenders() + << "filterfactories:" << rFactory.registeredFilters() + << "layoutfactories:" << rFactory.registeredLayouts() + << ")"; + return debug.space(); + } +#endif // QT_NO_DEBUG_STREAM + + + +} // namespace Log4Qt + diff --git a/src/log4qt/log4qt/helpers/factory.h b/src/log4qt/log4qt/helpers/factory.h new file mode 100644 index 0000000..b70104f --- /dev/null +++ b/src/log4qt/log4qt/helpers/factory.h @@ -0,0 +1,494 @@ +/****************************************************************************** + * + * package: Log4Qt + * file: factory.h + * created: September 2007 + * author: Martin Heinrich + * + * + * Copyright 2007 Martin Heinrich + * + * 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. + * + ******************************************************************************/ + +#ifndef LOG4QT_HELPERS_FACTORY_H +#define LOG4QT_HELPERS_FACTORY_H + + +/****************************************************************************** + * Dependencies + ******************************************************************************/ + +#include +#include +#include + +#include "ukui-logmacros.h" + +QT_BEGIN_NAMESPACE +class QMetaProperty; +class QObject; +QT_END_NAMESPACE + +/****************************************************************************** + * Declarations + ******************************************************************************/ + +namespace Log4Qt +{ + + class Appender; + class Filter; + class Layout; + + /*! + * \brief The class Factory provides factories for Appender, Filter and + * Layout objects. + * + * The functions createAppender(), createFilter() and createLayout() + * allow to create objects by specifying their class names. By default + * all classes of the package are recognised with their Log4j and Log4Qt + * classanmes. For example an object of the class FileAppender can be + * craeted using "org.apache.log4j.FileAppender" or "Log4Qt::FileAppender". + * Additional classes can be registered using registerAppender(), + * registerFilter() and registerLayout(). + * + * An QObject property can be set from a string value with + * setObjectProperty(). The function handles the required error checking + * and type conversion. + * + * \note All the functions declared in this class are thread-safe. + * + * \sa PropertyConfigurator + */ + class LIBUKUILOG4QT_EXPORT Factory + { + public: + /*! + * Prototype for an Appender factory function. The function creates + * an Appender object on the heap and returns a pointer to it. + * + * \sa registerAppender(), createAppender() + */ + typedef Appender *(*AppenderFactoryFunc)(); + + /*! + * Prototype for a Filter factory function. The function creates + * a Filter object on the heap and returns a pointer to it. + * + * \sa registerFilter(), createFilter() + */ + typedef Filter *(*FilterFactoryFunc)(); + + /*! + * Prototype for a Layout factory function. The function creates + * a Layout object on the heap and returns a pointer to it. + * + * \sa registerLayout(), createLayout() + */ + typedef Layout *(*LayoutFactoryFunc)(); + + private: + Factory(); + Q_DISABLE_COPY(Factory) + + public: + /*! + * Creates an object for the class \a rAppenderClassName on the heap + * and returns a pointer to it. If the class has no registered factory + * function a null pointer is returned. + * + * \sa registerAppender(), unregisterAppender(), registeredAppenders() + */ + static Appender *createAppender(const QString &rAppenderClassName); + + /*! + * This is an overloaded member function, provided for convenience. + */ + static Appender *createAppender(const char *pAppenderClassName); + + /*! + * Creates an object for the class \a rFilterClassName on the heap + * and returns a pointer to it. If the class has no registered factory + * function a null pointer is returned. + * + * \sa registerFilter(), unregisterFilter(), registeredFilters() + */ + static Filter *createFilter(const QString &rFilterClassName); + + /*! + * This is an overloaded member function, provided for convenience. + */ + static Filter *createFilter(const char *pFilterClassName); + + /*! + * Creates an object for the class \a rLayoutClassName on the heap + * and returns a pointer to it. If the class has no registered factory + * function a null pointer is returned. + * + * \sa registerLayout(), unregisterLayout(), registeredLayouts() + */ + static Layout *createLayout(const QString &rLayoutClassName); + + /*! + * This is an overloaded member function, provided for convenience. + */ + static Layout *createLayout(const char *pLayoutClassName); + + /*! + * Returns the Factory instance. + */ + static Factory *instance(); + + /*! + * Registers the Appender factory function \a pAppenderFactoryFunc + * for the class \a rAppenderClassName. If a registered factory + * function exists for the class, it is replaced with + * \a pAppenderFactoryFunc. + * + * \sa unregisterAppender(), registeredAppenders(), createAppender() + */ + static void registerAppender(const QString &rAppenderClassName, + AppenderFactoryFunc pAppenderFactoryFunc); + + /*! + * This is an overloaded member function, provided for convenience. + */ + static void registerAppender(const char *pAppenderClassName, + AppenderFactoryFunc pAppenderFactoryFunc); + + /*! + * Registers the Filter factory function \a pFilterFactoryFunc + * for the class \a rFilterClassName. If a registered factory + * function exists for the class, it is replaced with + * \a pFilterFactoryFunc. + * + * \sa unregisterFilter(), registeredFilters(), createFilter() + */ + static void registerFilter(const QString &rFilterClassName, + FilterFactoryFunc pFilterFactoryFunc); + + /*! + * This is an overloaded member function, provided for convenience. + */ + static void registerFilter(const char *pFilterClassName, + FilterFactoryFunc pFilterFactoryFunc); + + /*! + * Registers the Layout factory function \a pLayoutFactoryFunc + * for the class \a rLayoutClassName. If a registered factory + * function exists for the class, it is replaced with + * \a pLayoutFactoryFunc. + * + * \sa unregisterLayout(), registeredLayout(), createLayout() + */ + static void registerLayout(const QString &rLayoutClassName, + LayoutFactoryFunc pLayoutFactoryFunc); + + /*! + * This is an overloaded member function, provided for convenience. + */ + static void registerLayout(const char *pLayoutClassName, + LayoutFactoryFunc pLayoutFactoryFunc); + + /*! + * Returns a list of the class names for registered Appender factory + * functions. + * + * \sa registerAppender(), unregisterAppender() + */ + static QStringList registeredAppenders(); + + /*! + * Returns a list of the class names for registered Filter factory + * functions. + * + * \sa registerFilter(), unregisterFilter() + */ + static QStringList registeredFilters(); + + /*! + * Returns a list of the class names for registered Layout factory + * functions. + * + * \sa registerLayout(), unregisterLayout() + */ + static QStringList registeredLayouts(); + + /*! + * Sets the property \a rProperty of the object \a pObject to the + * value \a rValue. The function will test that the property + * \a rProperty is writeable and of a type the function can convert to. + * The types bool, int, Level and QString are supported. + * + * \sa OptionConverter + */ + static void setObjectProperty(QObject *pObject, + const QString &rProperty, + const QString &rValue); + + /*! + * This is an overloaded member function, provided for convenience. + */ + static void setObjectProperty(QObject *pObject, + const char *pProperty, + const QString &rValue); + + /*! + * Unregisters the Appender factory function for the class + * \a rAppenderClassName. + * + * \sa registerAppender(), registeredAppenders() + */ + static void unregisterAppender(const QString &rAppenderClassName); + + /*! + * This is an overloaded member function, provided for convenience. + */ + static void unregisterAppender(const char *pAppenderClassName); + + /*! + * Unregisters the Filter factory function for the class + * \a rFilterClassName. + * + * \sa registerFilter(), registeredFilters() + */ + static void unregisterFilter(const QString &rFilterClassName); + + /*! + * This is an overloaded member function, provided for convenience. + */ + static void unregisterFilter(const char *pFilterClassName); + + /*! + * Unregisters the Layout factory function for the class + * \a rLayoutClassName. + * + * \sa registerLayout(), registeredLayouts() + */ + static void unregisterLayout(const QString &rLayoutClassName); + + /*! + * This is an overloaded member function, provided for convenience. + */ + static void unregisterLayout(const char *pLayoutClassName); + + private: + Appender *doCreateAppender(const QString &rAppenderClassName); + Filter *doCreateFilter(const QString &rFilterClassName); + Layout *doCreateLayout(const QString &rLayoutClassName); + void doRegisterAppender(const QString &rAppenderClassName, + AppenderFactoryFunc pAppenderFactoryFunc); + void doRegisterFilter(const QString &rFilterClassName, + FilterFactoryFunc pFilterFactoryFunc); + void doRegisterLayout(const QString &rLayoutClassName, + LayoutFactoryFunc pLayoutFactoryFunc); + void doSetObjectProperty(QObject *pObject, + const QString &rProperty, + const QString &rValue); + void doUnregisterAppender(const QString &rAppenderClassName); + void doUnregisterFilter(const QString &rFilterClassName); + void doUnregisterLayout(const QString &rLayoutClassName); + void registerDefaultAppenders(); + void registerDefaultFilters(); + void registerDefaultLayouts(); + bool validateObjectProperty(QMetaProperty &rMetaProperty, + const QString &rProperty, + QObject *pObject); + + private: + mutable QMutex mObjectGuard; + QHash mAppenderRegistry; + QHash mFilterRegistry; + QHash mLayoutRegistry; + }; + + + /************************************************************************** + * Operators, Helper + **************************************************************************/ + +#ifndef QT_NO_DEBUG_STREAM + /*! + * \relates Factory + * + * Writes all object member variables to the given debug stream \a rDebug and + * returns the stream. + * + * + * %Factory(appenderfactories:("Log4Qt::DebugAppender", "Log4Qt::NullAppender", + * "Log4Qt::ConsoleAppender", "org.apache.log4j.varia.DebugAppender", + * "org.apache.log4j.FileAppender", "org.apache.log4j.RollingFileAppender", + * "org.apache.log4j.DailyRollingFileAppender", + * "org.apache.log4j.varia.ListAppender", + * "org.apache.log4j.varia.NullAppender", + * "Log4Qt::FileAppender", "org.apache.log4j.ConsoleAppender", + * "Log4Qt::DailyRollingFileAppender", "Log4Qt::ListAppender", + * "Log4Qt::RollingFileAppender") filterfactories: + * ("Log4Qt::DenyAllFilter", "Log4Qt::StringMatchFilter", + * "Log4Qt::LevelRangeFilter", "org.apache.log4j.varia.DenyAllFilter", + * "org.apache.log4j.varia.LevelRangeFilter", + * "org.apache.log4j.varia.StringMatchFilter", "Log4Qt::LevelMatchFilter", + * "org.apache.log4j.varia.LevelMatchFilter") layoutfactories: + * ("org.apache.log4j.SimpleLayout", "Log4Qt::PatternLayout", + * "Log4Qt::SimpleLayout", "org.apache.log4j.TTCCLayout", + * "Log4Qt::TTCCLayout", "org.apache.log4j.PatternLayout") ) + * + * \sa QDebug, Factory::logManager() + */ + QDebug operator<<(QDebug debug, + const Factory &rFactory); +#endif // QT_NO_DEBUG_STREAM + + + + /************************************************************************** + * Inline + **************************************************************************/ + + inline Appender *Factory::createAppender(const QString &rAppenderClassName) + { + return instance()->doCreateAppender(rAppenderClassName); + } + + inline Appender *Factory::createAppender(const char *pAppenderClassName) + { + return instance()->doCreateAppender(QLatin1String(pAppenderClassName)); + } + + inline Filter *Factory::createFilter(const QString &rFilterClassName) + { + return instance()->doCreateFilter(rFilterClassName); + } + + inline Filter *Factory::createFilter(const char *pFilterClassName) + { + return instance()->doCreateFilter(QLatin1String(pFilterClassName)); + } + + inline Layout *Factory::createLayout(const QString &rLayoutClassName) + { + return instance()->doCreateLayout(rLayoutClassName); + } + + inline Layout *Factory::createLayout(const char *pLayoutClassName) + { + return instance()->doCreateLayout(QLatin1String(pLayoutClassName)); + } + + inline void Factory::registerAppender(const QString &rAppenderClassName, + AppenderFactoryFunc pAppenderFactoryFunc) + { + instance()->doRegisterAppender(rAppenderClassName, pAppenderFactoryFunc); + } + + inline void Factory::registerAppender(const char *pAppenderClassName, + AppenderFactoryFunc pAppenderFactoryFunc) + { + instance()->doRegisterAppender(QLatin1String(pAppenderClassName), pAppenderFactoryFunc); + } + + inline void Factory::registerFilter(const QString &rFilterClassName, + FilterFactoryFunc pFilterFactoryFunc) + { + instance()->doRegisterFilter(rFilterClassName, pFilterFactoryFunc); + } + + inline void Factory::registerFilter(const char *pFilterClassName, + FilterFactoryFunc pFilterFactoryFunc) + { + instance()->doRegisterFilter(QLatin1String(pFilterClassName), pFilterFactoryFunc); + } + + inline void Factory::registerLayout(const QString &rLayoutClassName, + LayoutFactoryFunc pLayoutFactoryFunc) + { + instance()->doRegisterLayout(rLayoutClassName, pLayoutFactoryFunc); + } + + inline void Factory::registerLayout(const char *pLayoutClassName, + LayoutFactoryFunc pLayoutFactoryFunc) + { + instance()->doRegisterLayout(QLatin1String(pLayoutClassName), pLayoutFactoryFunc); + } + + inline QStringList Factory::registeredAppenders() + { + QMutexLocker locker(&instance()->mObjectGuard); + return instance()->mAppenderRegistry.keys(); + } + + inline QStringList Factory::registeredFilters() + { + QMutexLocker locker(&instance()->mObjectGuard); + return instance()->mFilterRegistry.keys(); + } + + inline QStringList Factory::registeredLayouts() + { + QMutexLocker locker(&instance()->mObjectGuard); + return instance()->mLayoutRegistry.keys(); + } + + inline void Factory::setObjectProperty(QObject *pObject, + const QString &rProperty, + const QString &rValue) + { + instance()->doSetObjectProperty(pObject, rProperty, rValue); + } + + inline void Factory::setObjectProperty(QObject *pObject, + const char *pProperty, + const QString &rValue) + { + instance()->doSetObjectProperty(pObject, QLatin1String(pProperty), rValue); + } + + inline void Factory::unregisterAppender(const QString &rAppenderClassName) + { + instance()->doUnregisterAppender(rAppenderClassName); + } + + inline void Factory::unregisterAppender(const char *pAppenderClassName) + { + instance()->doUnregisterAppender(QLatin1String(pAppenderClassName)); + } + + inline void Factory::unregisterFilter(const QString &rFilterClassName) + { + instance()->doUnregisterFilter(rFilterClassName); + } + + inline void Factory::unregisterFilter(const char *pFilterClassName) + { + instance()->doUnregisterFilter(QLatin1String(pFilterClassName)); + } + + inline void Factory::unregisterLayout(const QString &rLayoutClassName) + { + instance()->doUnregisterLayout(rLayoutClassName); + } + + inline void Factory::unregisterLayout(const char *pLayoutClassName) + { + instance()->doUnregisterLayout(QLatin1String(pLayoutClassName)); + } + +} // namespace Log4Qt + + +// Q_DECLARE_TYPEINFO(Log4Qt::Factory, Q_COMPLEX_TYPE); // use default + + +#endif // LOG4QT_HELPERS_FACTORY_H diff --git a/src/log4qt/log4qt/helpers/initialisationhelper.cpp b/src/log4qt/log4qt/helpers/initialisationhelper.cpp new file mode 100644 index 0000000..e8ba59b --- /dev/null +++ b/src/log4qt/log4qt/helpers/initialisationhelper.cpp @@ -0,0 +1,185 @@ +/****************************************************************************** + * + * package: Log4Qt + * file: initialisationhelper.cpp + * created: September 2007 + * author: Martin Heinrich + * + * + * changes Feb 2009, Martin Heinrich + * - Fixed VS 2008 unreferenced formal parameter warning by using + * Q_UNUSED in operator<<. + * + * + * Copyright 2007 - 2009 Martin Heinrich + * + * 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. + * + ******************************************************************************/ + + + +/****************************************************************************** + * Dependencies + ******************************************************************************/ + + +#include "log4qt/helpers/initialisationhelper.h" + +#include +#include +#include +#include +#include +#ifndef QT_NO_DATASTREAM +#include +#endif +#include "log4qt/helpers/datetime.h" +#include "log4qt/helpers/logerror.h" +#include "log4qt/loggingevent.h" + + + +namespace Log4Qt +{ + + + /************************************************************************** + *Declarations + **************************************************************************/ + + + + /************************************************************************** + * C helper functions + **************************************************************************/ + + + + /************************************************************************** + * Class implementation: InitialisationHelper + **************************************************************************/ + + + InitialisationHelper::InitialisationHelper() : + mStartTime(DateTime::currentDateTime().toMilliSeconds()), + mEnvironmentSettings() + { + doRegisterTypes(); + doInitialiseEnvironmentSettings(); + } + + + InitialisationHelper::~InitialisationHelper() + { + Q_ASSERT_X(false, "InitialisationHelper::~InitialisationHelper()", "Unexpected destruction of singleton object"); + } + + + LOG4QT_IMPLEMENT_INSTANCE(InitialisationHelper) + + + void InitialisationHelper::doInitialiseEnvironmentSettings() + { + // Is Process::systemEnvironment() safe to be used before a QCoreApplication + // object has been created? + + QStringList setting_keys; + setting_keys << QLatin1String("Debug"); + setting_keys << QLatin1String("DefaultInitOverride"); + setting_keys << QLatin1String("Configuration"); + setting_keys << QLatin1String("ConfiguratorClass"); + + QHash env_keys; + QString entry; + Q_FOREACH(entry, setting_keys) + env_keys.insert(QString::fromLatin1("log4qt_").append(entry).toUpper(), entry); + + QStringList sys_env = QProcess::systemEnvironment(); + Q_FOREACH(entry, sys_env) + { + int i = entry.indexOf(QLatin1Char('=')); + if (i == -1) + continue; + QString key = entry.left(i); + QString value = entry.mid(i + 1).trimmed(); + if (env_keys.contains(key)) + mEnvironmentSettings.insert(env_keys.value(key), value); + } + } + + + void InitialisationHelper::doRegisterTypes() + { + qRegisterMetaType("Log4Qt::LogError"); + qRegisterMetaType("Log4Qt::Level"); + qRegisterMetaType("Log4Qt::LoggingEvent"); + + #ifndef QT_NO_DATASTREAM + qRegisterMetaTypeStreamOperators("Log4Qt::LogError"); + qRegisterMetaTypeStreamOperators("Log4Qt::Level"); + qRegisterMetaTypeStreamOperators("Log4Qt::LoggingEvent"); + #endif + } + + + QString InitialisationHelper::doSetting(const QString &rKey, + const QString &rDefault) const + { + if (mEnvironmentSettings.contains(rKey)) + return mEnvironmentSettings.value(rKey); + + if (QCoreApplication::instance()) + { + QSettings s; + s.beginGroup(QLatin1String("Log4Qt")); + return s.value(rKey, rDefault).toString().trimmed(); + } + else + return rDefault; + } + + + bool InitialisationHelper::staticInitialisation() + { + instance(); + return true; + } + + + bool InitialisationHelper::msStaticInitialisation = staticInitialisation(); + + + + /************************************************************************** + * Implementation: Operators, Helper + **************************************************************************/ + + +#ifndef QT_NO_DEBUG_STREAM + QDebug operator<<(QDebug debug, + const InitialisationHelper &rInitialisationHelper) + { + Q_UNUSED(rInitialisationHelper); + debug.nospace() << "InitialisationHelper(" + << "starttime:" << InitialisationHelper::startTime() + << "(" << DateTime::fromMilliSeconds(InitialisationHelper::startTime()) << ")" + << "environmentsettings:" << InitialisationHelper::environmentSettings() + << ")"; + return debug.space(); + } +#endif // QT_NO_DEBUG_STREAM + + + +} // namespace Log4Qt diff --git a/src/log4qt/log4qt/helpers/initialisationhelper.h b/src/log4qt/log4qt/helpers/initialisationhelper.h new file mode 100644 index 0000000..f6c531c --- /dev/null +++ b/src/log4qt/log4qt/helpers/initialisationhelper.h @@ -0,0 +1,437 @@ +/****************************************************************************** + * + * package: Log4Qt + * file: initialisationhelper.h + * created: September 2007 + * author: Martin Heinrich + * + * + * changes: Sep 2008, Martin Heinrich: + * - Replaced usage of q_atomic_test_and_set_ptr with + * QBasicAtomicPointer + * + * + * Copyright 2007 - 2008 Martin Heinrich + * + * 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. + * + ******************************************************************************/ + +#ifndef LOG4QT_HELPERS_INITIALISATIONHELPER_H +#define LOG4QT_HELPERS_INITIALISATIONHELPER_H + + +/****************************************************************************** + * Dependencies + ******************************************************************************/ + +#include +#include +#include + +#include "ukui-logmacros.h" + +#if QT_VERSION >= QT_VERSION_CHECK(4, 4, 0) +# ifndef Q_ATOMIC_POINTER_TEST_AND_SET_IS_ALWAYS_NATIVE +# warning "QAtomicPointer test and set is not native. The macros Log4Qt::LOG4QT_GLOBAL_STATIC and Log4Qt::LOG4QT_IMPLEMENT_INSTANCE are not thread-safe." +# endif +#endif + + +/****************************************************************************** + * Declarations + ******************************************************************************/ + +class QMutex; + +namespace Log4Qt +{ + /*! + * LOG4QT_GLOBAL_STATIC declares a static function \a FUNCTION that + * returns a pointer to a singleton object of the type \a TYPE. + * + * The macro uses a static variable to store a pointer to the singleton + * object. On the first invocation an object of the type \a TYPE is created + * on the heap and the pointer is set. Any further invocations will return + * the stored pointer. If multiple threads are accessing the function + * without the pointer being set, each thread will create an object of the + * type \a TYPE. The threads that find the pointer already been set will + * delete their object. The singleton object will not be deleted during static + * de-initialisation. + * + * The following example uses a global global mutex object to synchronise + * access to a static member variable. + * + * \code + * #file: myclass.h + * + * class MyClass + * { + * public: + * MyClass(); + * ~MyClass(); + * private: + * static qint64 msObjectCount; + * } + * \endcode + * \code + * #file: myclass.cpp + * + * #include myclass.h + * + * LOG4QT_GLOBAL_STATIC(QMutex, class_guard) + * + * MyClass::MyClass() + * { + * QMutexLocker(class_guard()); + * msObjectCount++; + * } + * + * MyClass::~MyClass() + * { + * QMutexLocker(class_guard()); + * msObjectCount--; + * } + * + * qint64 MyClass::msObjectCount = 0; + * \endcode + * + * \note The function created by the macro is thread-safe. + * + * \sa \ref Log4Qt::LOG4QT_IMPLEMENT_INSTANCE "LOG4QT_IMPLEMENT_INSTANCE", + * \ref Log4Qt::InitialisationHelper "InitialisationHelper" + */ +#if QT_VERSION < QT_VERSION_CHECK(4, 4, 0) + #define LOG4QT_GLOBAL_STATIC(TYPE, FUNCTION) \ + static volatile TYPE *sp_global_static_##FUNCTION = 0; \ + TYPE *FUNCTION() \ + { \ + if (!sp_global_static_##FUNCTION) \ + { \ + TYPE *p_temp = new TYPE; \ + if (!q_atomic_test_and_set_ptr(&sp_global_static_##FUNCTION, \ + 0, p_temp)) \ + delete p_temp; \ + } \ + return const_cast(sp_global_static_##FUNCTION); \ + } +#elif QT_VERSION < QT_VERSION_CHECK(5, 0, 0) + #define LOG4QT_GLOBAL_STATIC(TYPE, FUNCTION) \ + static QBasicAtomicPointer sp_global_static_##FUNCTION = \ + Q_BASIC_ATOMIC_INITIALIZER(0); \ + TYPE *FUNCTION() \ + { \ + if (!sp_global_static_##FUNCTION) \ + { \ + TYPE *p_temp = new TYPE; \ + if (!sp_global_static_##FUNCTION.testAndSetOrdered(0, \ + p_temp)) \ + delete p_temp; \ + } \ + return sp_global_static_##FUNCTION; \ + } +#else + #define LOG4QT_GLOBAL_STATIC(TYPE, FUNCTION) \ + static QBasicAtomicPointer sp_global_static_##FUNCTION = \ + Q_BASIC_ATOMIC_INITIALIZER(0); \ + TYPE *FUNCTION() \ + { \ + if (!sp_global_static_##FUNCTION.loadAcquire()) \ + { \ + TYPE *p_temp = new TYPE; \ + if (!sp_global_static_##FUNCTION.testAndSetOrdered(0, \ + p_temp)) \ + delete p_temp; \ + } \ + return sp_global_static_##FUNCTION.loadAcquire(); \ + } +#endif + + /*! + * LOG4QT_IMPLEMENT_INSTANCE implements an instance function for a + * singleton class \a TYPE. + * + * The function works like the one created by + * \ref Log4Qt::LOG4QT_GLOBAL_STATIC "LOG4QT_GLOBAL_STATIC". + * + * The following example illustrates how to use the macro to create a + * singleton class: + * + * \code + * #file: mysingleton.h + * + * class MySingleton + * { + * private: + * MySingleton(); + * ~MySingleton(); + * public: + * MySingleton *instance(); + * } + * \endcode + * \code + * #file: mysingleton.cpp + * + * #include mysingleton.h + * + * MySingleton::MySingleton() + * {} + * + * MySingleton::~MySingleton() + * {} + * + * LOG4QT_IMPLEMENT_INSTANCE(MySingleton) + * + * \endcode + * + * \note The function created by the macro is thread-safe. + * + * \sa \ref Log4Qt::LOG4QT_GLOBAL_STATIC "LOG4QT_GLOBAL_STATIC", + * \ref Log4Qt::InitialisationHelper "InitialisationHelper" + */ +#if QT_VERSION < QT_VERSION_CHECK(4, 4, 0) + #define LOG4QT_IMPLEMENT_INSTANCE(TYPE) \ + static TYPE *sp_singleton_##TYPE = 0; \ + TYPE *TYPE::instance() \ + { \ + if (!sp_singleton_##TYPE) \ + { \ + TYPE *p_temp = new TYPE; \ + if (!q_atomic_test_and_set_ptr(&sp_singleton_##TYPE, \ + 0, p_temp)) \ + delete p_temp; \ + } \ + return sp_singleton_##TYPE; \ + } +#elif QT_VERSION < QT_VERSION_CHECK(5, 0, 0) + #define LOG4QT_IMPLEMENT_INSTANCE(TYPE) \ + static QBasicAtomicPointer sp_singleton_##TYPE = \ + Q_BASIC_ATOMIC_INITIALIZER(0); \ + TYPE *TYPE::instance() \ + { \ + if (!sp_singleton_##TYPE) \ + { \ + TYPE *p_temp = new TYPE; \ + if (!sp_singleton_##TYPE.testAndSetOrdered(0, p_temp)) \ + delete p_temp; \ + } \ + return sp_singleton_##TYPE; \ + } +#else + #define LOG4QT_IMPLEMENT_INSTANCE(TYPE) \ + static QBasicAtomicPointer sp_singleton_##TYPE = \ + Q_BASIC_ATOMIC_INITIALIZER(0); \ + TYPE *TYPE::instance() \ + { \ + if (!sp_singleton_##TYPE.loadAcquire()) \ + { \ + TYPE *p_temp = new TYPE; \ + if (!sp_singleton_##TYPE.testAndSetOrdered(0, p_temp)) \ + delete p_temp; \ + } \ + return sp_singleton_##TYPE.loadAcquire(); \ + } +#endif + + /*! + * \brief The class InitialisationHelper performs static initialisation + * tasks. + * + * The InitialisationHelper is either created on the first call or through + * static initialisation. It will capture the programs startup time, + * which can be retrieved using startTime(). The system environment + * is analysed for package related definitions. The result is available + * over environmentSettings(). The packages custom types are registered with + * the Qt type system. + * + * Settings for the package can be retrieved using setting(). Two macros + * are available to help with the creation of singletons / global static + * objects (\ref Log4Qt::LOG4QT_GLOBAL_STATIC "LOG4QT_GLOBAL_STATIC" and + * \ref Log4Qt::LOG4QT_IMPLEMENT_INSTANCE "LOG4QT_IMPLEMENT_INSTANCE"). + * + * \note All the functions declared in this class are thread-safe. + * + * \sa \ref Init "Initialization procedure", + */ + class LIBUKUILOG4QT_EXPORT InitialisationHelper + { + private: + InitialisationHelper(); + InitialisationHelper(const InitialisationHelper &rOther); // Not implemented + virtual ~InitialisationHelper(); + InitialisationHelper &operator=(const InitialisationHelper &rOther); // Not implemented + + public: + + /*! + * Returns a hash with the settings retrieved from the system + * environment on startup. + * + * The following table shows the environment variables taken into + * account and the setting key used for them. + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + *
Environment variable Setting key
LOG4QT_DEBUG Debug
LOG4QT_DEFAULTINITOVERRIDE DefaultInitOverride
LOG4QT_CONFIGURATION Configuration
LOG4QT_CONFIGURATORCLASS ConfiguratorClass
+ * + * \sa \ref Env "Environment Variables", + * setting() + */ + static QHash environmentSettings(); + + /*! + * Returns the InitialisationHelper instance. + */ + static InitialisationHelper *instance(); + + /*! + * Returns the value for the setting \a rKey or \a rDefault, if it is + * not defined. + * + * A setting can be either defined by an environment variable or by a + * key in the application setting. The function will first test the + * settings made by environment variables for the key \a rKey using + * environmentSettings(). If the key is not present and a + * QCoreApplication exists, the application settings are tested for + * the key \a rKey in the group \c %Log4Qt. + * + * The following setting exists: + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + *
Setting key Description
Debug The variable controls the Level value for the logger + * LogManager::logLogger(). If the value is a valid Level string, + * the level for the logger is set to the level. If the value is not + * a valid Level string, \ref Level::DEBUG_INT "DEBUG_INT" is used. + * Otherwise \ref Level::ERROR_INT "ERROR_INT" is used.
DefaultInitOverride The variable controls the \ref Init "initialization procedure" + * performed by the \ref LogManager "LogManager" on startup. + * If it is set to any other value then \c false the \ref Init + * "initialization procedure" is skipped.
Configuration Specifies the configuration file used for initialising the package.
ConfiguratorClass Specifies the configurator class used for initialising the package.
+ * + * \sa environmentSettings(), \ref Env "Environment Variables", + * \ref Init "Initialization procedure", + * LogManager::configureLogLogger(), LogManager::startup() + */ + static QString setting(const QString &rKey, + const QString &rDefault = QString()); + + /*! + * Returns the start time of the program as the number of milliseconds + * that have passed since 1970-01-01T00:00:00,000, Coordinated + * Universal Time (Qt::UTC). + * + * \sa DateTime::fromMilliSeconds(), + * DateTime::toMilliSeconds() + */ + static qint64 startTime(); + + private: + void doInitialiseEnvironmentSettings(); + void doRegisterTypes(); + QString doSetting(const QString &rKey, + const QString &rDefault) const; + static bool shutdown(); + static bool staticInitialisation(); + + private: + // QMutex mObjectGuard; + const qint64 mStartTime; + QHash mEnvironmentSettings; + static bool msStaticInitialisation; + +#ifndef QT_NO_DEBUG_STREAM + // Needs to be friend to access details + friend QDebug operator<<(QDebug debug, + const InitialisationHelper &rInitialisationHelper); +#endif // QT_NO_DEBUG_STREAM + }; + + + /************************************************************************** + * Operators, Helper + **************************************************************************/ + +#ifndef QT_NO_DEBUG_STREAM + /*! + * \relates InitialisationHelper + * + * Writes all object member variables to the given debug stream \a rDebug and + * returns the stream. + * + * + * %InitialisationHelper(InitialisationHelper(starttime:1193883677438( + * QDateTime("Wed Oct 31 21:21:17 2007") ) + * environmentsettings: QHash(("configuration", "\myapp.log4j") + * ("Debug", "DEBUG")) ) ) + * + * \sa QDebug, InitialisationHelper::logManager() + */ + QDebug operator<<(QDebug debug, + const InitialisationHelper &rInitialisationHelper); +#endif // QT_NO_DEBUG_STREAM + + + /************************************************************************** + * Inline + **************************************************************************/ + + inline QHash InitialisationHelper::environmentSettings() + { // QMutexLocker locker(&instance()->mObjectGuard); // Constant for object lifetime + return instance()->mEnvironmentSettings; } + + inline QString InitialisationHelper::setting(const QString &rKey, + const QString &rDefault) + { // QMutexLocker locker(&instance()->mObjectGuard); // Reentrant and const + return instance()->doSetting(rKey, rDefault); } + + inline qint64 InitialisationHelper::startTime() + { // QMutexLocker locker(&instance()->mObjectGuard); // Constant for object lifetime + return instance()->mStartTime; } + +} // namespace Log4Qt + + +// Q_DECLARE_TYPEINFO(Log4Qt::InitialisationHelper, Q_COMPLEX_TYPE); // use default + + +#endif // LOG4QT_HELPERS_INITIALISATIONHELPER_H diff --git a/src/log4qt/log4qt/helpers/logerror.cpp b/src/log4qt/log4qt/helpers/logerror.cpp new file mode 100644 index 0000000..f78d2ab --- /dev/null +++ b/src/log4qt/log4qt/helpers/logerror.cpp @@ -0,0 +1,354 @@ +/****************************************************************************** + * + * package: Log4Qt + * file: logerror.cpp + * created: September 2007 + * author: Martin Heinrich + * + * + * Copyright 2007 Martin Heinrich + * + * 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. + * + ******************************************************************************/ + + + +/****************************************************************************** + * Dependencies + *****************************************************************************/ + + +#include "log4qt/helpers/logerror.h" + +#include +#include +#include +#include +#include +#include +#include +#include "log4qt/helpers/initialisationhelper.h" + + +namespace Log4Qt +{ + + + /************************************************************************** + * Declarations + **************************************************************************/ + + + typedef QThreadStorage ThreadError; + + + + /************************************************************************** + * C helper functions + **************************************************************************/ + + + LOG4QT_GLOBAL_STATIC(ThreadError, thread_error) + + + + /************************************************************************** + * Class implementation: LogError + **************************************************************************/ + + + LogError::LogError() : + mCode(0), + mContext(), + mMessage(), + mSymbol(), + mArgs(), + mCausingErrors() + { + } + + + LogError::LogError(const QString &rMessage, + int code, + const QString &rSymbol, + const QString &rContext) : + mCode(code), + mContext(rContext), + mMessage(cleanMessage(rMessage)), + mSymbol(rSymbol), + mArgs(), + mCausingErrors() + { + } + + + LogError::LogError(const char *pMessage, + int code, + const char *pSymbol, + const char *pContext, + Encoding encoding) : + mCode(code), + mContext(QString::fromLatin1(pContext)), + mMessage(), + mSymbol(QString::fromLatin1(pSymbol)), + mArgs(), + mCausingErrors() + { + switch(encoding) + { + case LATIN1: + mMessage = QString::fromLatin1(pMessage); + break; + case CODECFORTR: +#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0) + mMessage = QTextCodec::codecForTr()->toUnicode(pMessage); +#else + mMessage = QString::fromUtf8(pMessage); +#endif + break; + case UNICODEUTF8: + mMessage = QString::fromUtf8(pMessage); + break; + default: + Q_ASSERT_X(false, "LogError::LogError", "Unkown encoding constant"); + mMessage = QString::fromLatin1(pMessage); + } + mMessage = cleanMessage(mMessage); + + if (mSymbol == QString::number(mCode)) + mSymbol.clear(); + } + + + QString LogError::translatedMessage() const + { +#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0) + return QCoreApplication::translate(mContext.toLatin1(), mMessage.toUtf8().data(), 0, QCoreApplication::UnicodeUTF8); +#else + return QCoreApplication::translate(mContext.toLatin1(), mMessage.toUtf8().data(), 0); +#endif + } + + + LogError LogError::lastError() + { + if (!thread_error()->hasLocalData()) + return LogError(); + else + return *thread_error()->localData(); + } + + + void LogError::setLastError(const LogError &rLogError) + { + if (!thread_error()->hasLocalData()) + thread_error()->setLocalData(new LogError); + + *thread_error()->localData() = rLogError; + } + + + QString LogError::toString() const + { + QString result = messageWithArgs(); + + QString context_symbol = mContext; + if (!context_symbol.isEmpty() && !mSymbol.isEmpty()) + context_symbol.append(QLatin1String("::")); + context_symbol.append(mSymbol); + + if (!context_symbol.isEmpty() || mCode) + { + result.append(QLatin1String(" (")); + if (!context_symbol.isEmpty()) + result.append(context_symbol); + if (!context_symbol.isEmpty() && mCode) + result.append(QLatin1String(", ")); + if (mCode) + result.append(QString::number(mCode)); + result.append(QLatin1String(")")); + } + + if (!mCausingErrors.isEmpty()) + { + QString causing_errors_str = QLatin1String(": ") + mCausingErrors.at(0).toString(); + int i = 1; + while (i < mCausingErrors.count()) + { + causing_errors_str.append(QLatin1String(", ")).append(mCausingErrors.at(i).toString()); + i++; + } + result.append(causing_errors_str); + } + + return result; + } + + + QString LogError::insertArgs(const QString &rMessage) const + { + QString result; + + /* + + // Don't use a loop to be able to handle arguments that conatin strings + // like %1. + // Using this method only 9 arguments can be handled as the %1 + // in %11 gets also replaced with the first argument. + + switch (mArgs.count()) + { + case 0: + break; + case 1: + result = rMessage.arg(mArgs.at(0)); + break; + case 2: + result = rMessage.arg(mArgs.at(0), mArgs.at(1)); + break; + case 3: + result = rMessage.arg(mArgs.at(0), mArgs.at(1), mArgs.at(2)); + break; + case 4: + result = rMessage.arg(mArgs.at(0), mArgs.at(1), mArgs.at(2), mArgs.at(3)); + break; + case 5: + result = rMessage.arg(mArgs.at(0), mArgs.at(1), mArgs.at(2), mArgs.at(3), mArgs.at(4)); + break; + case 6: + result = rMessage.arg(mArgs.at(0), mArgs.at(1), mArgs.at(2), mArgs.at(3), mArgs.at(4), mArgs.at(5)); + break; + case 7: + result = rMessage.arg(mArgs.at(0), mArgs.at(1), mArgs.at(2), mArgs.at(3), mArgs.at(4), mArgs.at(5), mArgs.at(6)); + break; + case 8: + result = rMessage.arg(mArgs.at(0), mArgs.at(1), mArgs.at(2), mArgs.at(3), mArgs.at(4), mArgs.at(5), mArgs.at(6), mArgs.at(7)); + break; + default: + result = rMessage.arg(mArgs.at(0), mArgs.at(1), mArgs.at(2), mArgs.at(3), mArgs.at(4), mArgs.at(5), mArgs.at(6), mArgs.at(7), mArgs.at(8)); + break; + } + + if (mArgs.count() > 9) + { + int i = 9; + while(i < mArgs.count()) + { + result = result.arg(mArgs.at(i)); + i++; + } + } + */ + + result = rMessage; + QVariant arg; + Q_FOREACH(arg, mArgs) + result = result.arg(arg.toString()); + return result; + } + + + QString LogError::cleanMessage(const QString &rMessage) + { + if (rMessage.isEmpty()) + return rMessage; + + QString result = rMessage; + if (rMessage.at(rMessage.size() - 1) == QLatin1Char('.')) + result = rMessage.left(rMessage.size() - 1); + return result; + } + + + + /************************************************************************** + * Implementation: Operators, Helper + **************************************************************************/ + + +#ifndef QT_NO_DATASTREAM + QDataStream &operator<<(QDataStream &rStream, + const LogError &rLogError) + { + QBuffer buffer; + buffer.open(QIODevice::WriteOnly); + QDataStream stream(&buffer); + + // version + quint16 version = 0; + stream << version; + // version 0 data + stream << rLogError.mCode + << rLogError.mContext + << rLogError.mMessage + << rLogError.mSymbol + << rLogError.mArgs + << rLogError.mCausingErrors; + + buffer.close(); + rStream << buffer.buffer(); + return rStream; + } + + + QDataStream &operator>>(QDataStream &rStream, + LogError &rLogError) + { + QByteArray array; + rStream >> array; + QBuffer buffer(&array); + buffer.open(QIODevice::ReadOnly); + QDataStream stream(&buffer); + + // version + quint16 version; + stream >> version; + // Version 0 data + QString level; + QString logger; + stream >> rLogError.mCode + >> rLogError.mContext + >> rLogError.mMessage + >> rLogError.mSymbol + >> rLogError.mArgs + >> rLogError.mCausingErrors; + + buffer.close(); + return rStream; + } +#endif // QT_NO_DATASTREAM + + +#ifndef QT_NO_DEBUG_STREAM + QDebug operator<<(QDebug debug, + const LogError &rLogError) + { + // Escape % sign + QString message = rLogError.message(); + message.replace(QLatin1String("%"), QLatin1String("%%")); + + debug.nospace() << "LogError(" + << "code:" << rLogError.code() << " " + << "context:" << rLogError.context() << " " + << "message:" << message << " " + << "symbol:" << rLogError.symbol() << " " + << "args:" << rLogError.args() + << "translatedMessage:" << rLogError.translatedMessage() + << ")"; + return debug.maybeSpace(); + } +#endif // QT_NO_DEBUG_STREAM + + +} // namespace Log4Qt diff --git a/src/log4qt/log4qt/helpers/logerror.h b/src/log4qt/log4qt/helpers/logerror.h new file mode 100644 index 0000000..3c83135 --- /dev/null +++ b/src/log4qt/log4qt/helpers/logerror.h @@ -0,0 +1,552 @@ +/****************************************************************************** + * + * package: Log4Qt + * file: logerror.h + * created: September 2007 + * author: Martin Heinrich + * + * + * Copyright 2007 Martin Heinrich + * + * 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. + * + ******************************************************************************/ + +#ifndef LOG4QT_LOGERROR_H +#define LOG4QT_LOGERROR_H + + +/****************************************************************************** + * Dependencies + ******************************************************************************/ + +#include +#include + +#include "ukui-logmacros.h" + + +/****************************************************************************** + * Declarations + ******************************************************************************/ + +namespace Log4Qt +{ + /*! + * Creates an LogError object with the error message \a message, the error + * code \a code and the context \a context. The symbol of the error is + * set to \a code as string value. + * + * The following example logs an error, if a character is not a digit. + * + * \code + * if (!c.isDigit()) + * { + * Error e = LOG4QT_ERROR(QT_TR_NOOP("Found character '%1' where digit was expected."), + * LAYOUT_EXPECTED_DIGIT_ERROR, + * "Log4Qt::PatternFormatter"); + * e << QString(c); + * logger()->error(e); + * } + * \endcode + */ + #define LOG4QT_ERROR(message, code, context) \ + LogError(message, code, #code, context) + + /*! + * Creates an LogError object with the error message \a message and the + * error code \a code. The symbol of the error is set to \a code as string + * value. The context is set to the class name of the current object. The + * current objects class must be derived from QObject. + * + * The following example handles an error while opening a file. + * + * \code + * if (!mpFile->open(mode)) + * { + * LogError e = LOG4QT_QCLASS_ERROR(QT_TR_NOOP("Unable to open file '%1' for appender '%2'"), + * APPENDER_OPENING_FILE_ERROR); + * e << mFileName << name(); + * e.addCausingError(LogError(mpFile->errorString(), mpFile->error())); + * logger()->error(e); + * return; + * } + * \endcode + */ + #define LOG4QT_QCLASS_ERROR(message, code) \ + LogError(message, code, #code, this->metaObject()->className()) + + /*! + * \brief The class LogError represents an error. + * + * The class error allows storing error information in a structured way. + * The error message is stored separately from the information that may be + * substituted into the message string. This way it is possible to access + * all information after the error has been raised. It also allows to + * translate the error at a later point in time or to get a translated and + * a not translated error text (e.g. translated for the UI and not + * translated for a log). + * + * The message is accessed using message() and setMessage(). Arguments for + * the message can be added using addArg() or operator<<(). The arguments + * can be retrieved using args(). The message with substituted arguments + * is returned by messageWithArgs(). + * + * An error code can be set as integer value code() and/or a symbolic value + * symbol(). + * + * To allow the translation of the message the error stores the translation + * context (context(), setContext()). The translated message can be accessed + * using translatedMessage() or using translatedMessageWithArgs(), if it + * should contain the arguments. + * + * An error can have one or more related errors that caused it. An error is + * related using addCausingError(). All causing errors can be retrieved using + * causingErrors(). + * + * A per thread error can be maintained using lastError() and setLastError(). + * + * There are two macros avaiable to simplify the error creation. The macro + * \ref Log4Qt::LOG4QT_ERROR "LOG4QT_ERROR" is used with classes not derived + * from QObject. The macro \ref Log4Qt::LOG4QT_QCLASS_ERROR "LOG4QT_QCLASS_ERROR" + * is used with classes derived from QObject. + */ + class LIBUKUILOG4QT_EXPORT LogError + { + public: + + /*! + * The enum Encoding defines the 8-bit encoding of a character string + * arguments to \ref LogError::LogError(const char *, int, const char *, + * const char *, Encoding) "LogError::LogError()". + * + * \sa \ref LogError::LogError(const char *, int, const char *, const char *, Encoding) "LogError::LogError()" + */ + enum Encoding + { + /*! LATIN-1 */ + LATIN1, + /*! + * The encoding specified by QTextCodec::codecForTr() + * (Latin-1 if none has been set). + */ + CODECFORTR, + /*! UTF-8 */ + UNICODEUTF8 + }; + Q_ENUMS(Encoding) + + /*! + * Creates an empty error. The error code is set to 0 and all other + * members are set to be empty. + * + * \sa isEmpty() + */ + LogError(); + + /*! + * Creates an error with the Message \a rMessage and the error code + * \a code. The symbol for the error code is set to \a rSymbol and the + * context to \a rContext. + * + * \a rContext must be string that can be converted to Latin-1. The + * Latin-1 representation of the string is used with + * QApplication::translate(), if a translation for \a rMessage is + * requested. + * + * \sa translatedMessage(), translatedMessageWithArgs() + */ + LogError(const QString &rMessage, + int code = 0, + const QString &rSymbol = QString(), + const QString &rContext = QString()); + + /*! + * Creates an error with the Message \a pMessage and the error code + * \a code. The symbol for the error code is set to \a pSymbol and the + * context to \a pContext. + * + * \a encoding specifies the encoding of \a pMessage. \a pSymbol and + * \a pContext are expected to be Latin-1. + * + * \note To support the macros \ref Log4Qt::LOG4QT_ERROR "LOG4QT_ERROR" + * and \ref Log4Qt::LOG4QT_QCLASS_ERROR "LOG4QT_QCLASS_ERROR" + * the function tests, if \a pSymbol is the string representation of + * \a code. If it is, the symbol is set to be empty. Otherwise symbol + * is set to \a pSymbol. + * + * \sa translatedMessage(), translatedMessageWithArgs() + */ + LogError(const char *pMessage, + int code = 0, + const char *pSymbol = 0, + const char *pContext = 0, + Encoding encoding = LATIN1); + + // LogError(const LogError &rOther); // Use compiler default + // virtual ~LogError(); // Use compiler default + // LogError &operator=(const LogError &rOther); // Use compiler default + + /*! + * Returns the error code. + * + * \sa setCode() + */ + int code() const; + + /*! + * Returns the context for the error. + * + * \sa setContext() + */ + QString context() const; + + /*! + * Returns the error message. + * + * \sa setMessage() + */ + QString message() const; + + /*! + * Returns the symbol for the error code. + * + * \sa setSymbol() + */ + QString symbol() const; + + /*! + * Returns the translated error message. + * + * The translated message is created by calling + * QCoreApplication::translate() using context().toLatin1() as + * context and message.toUtf8() as message. + * + * \sa translatedMessageWithArgs() + */ + QString translatedMessage() const; + + /*! + * Sets the error code to \a code. + * + * \sa code() + */ + void setCode(int code); + + /*! + * Sets the context to \a rClassName. + * + * \a rContext must be string that can be converted to Latin-1. The + * Latin-1 representation of the string is used with + * QApplication::translate(), if a translation for \a rMessage is + * requestd. + * + * \sa context(), translatedMessage(), translatedMessageWithArgs() + */ + void setContext(const QString &rClassName); + + /*! + * Sets the error message to \a rMessage + * + * \sa message() + */ + void setMessage(const QString &rMessage); + + /*! + * Sets the symbol for the error code to \a rSymbol. + * + * \sa symbol() + */ + void setSymbol(const QString &rSymbol); + + /*! + * Returns the last error set for the current thread using + * setLastError(). + * + * \note: This function is thread-safe. + * + * \sa setLastError() + */ + static LogError lastError(); + + /*! + * Sets the last error for the current thread to \a rLogError. + * + * \note: This function is thread-safe. + * + * \sa lastError() + */ + static void setLastError(const LogError &rLogError); + + /*! + * Appends \a rArg to the list of arguments and returns a reference to + * this error. + * + * \sa operator<<(), args(), clearArgs() + */ + LogError &addArg(const QVariant &rArg); + + /*! + * This is an overloaded member function, provided for convenience. + */ + LogError &addArg(int arg); + + /*! + * This is an overloaded member function, provided for convenience. + */ + LogError &addArg(const QString &rArg); + + /*! + * Appends \a rLogError to the list of causing errors and returns a + * reference to this error. + * + * \sa causingErrors(), clearCausingErrors() + */ + LogError &addCausingError(const LogError &rLogError); + + /*! + * Returns the list of arguments that have been added to this error. + * + * \sa addArg(), operator<<(), clearArgs() + */ + QList args() const; + + /*! + * Returns the list of causing errors that have been added to this error. + * + * \sa addArg(), operator<<(), clearArgs() + */ + QList causingErrors() const; + + /*! + * Clears the list of arguments that have been added to this error. + * + * \sa addArg(), operator<<(), args() + */ + void clearArgs(); + + /*! + * Clears the list of causing errors that have been added to this error. + * + * \sa addCausingError(), causingErrors() + */ + void clearCausingErrors(); + + /*! + * Returns true, if the error code is 0 and the message is empty. + * Otherwise it returns false. + * + * \sa code(), message() + */ + bool isEmpty() const; + + /*! + * Returns the message with arguments. The arguments are incoorporated + * into the messag using QString::arg(). + * + * \sa QString::arg(), translatedMessageWithArgs() + */ + QString messageWithArgs() const; + + /*! + * Returns the translated message with arguments. The arguments are + * incoorporated into the messag using QString::arg(). + * + * \sa QString::arg(), messageWithArgs(), translatedMessage() + */ + QString translatedMessageWithArgs() const; + + /*! + * Appends \a rArg to the list of arguments and returns a reference to + * this error. + * + * \sa addArg() + */ + LogError &operator<<(const QVariant &rArg); + + /*! + * This is an overloaded member function, provided for convenience. + */ + LogError &operator<<(int arg); + + /*! + * This is an overloaded member function, provided for convenience. + */ + LogError &operator<<(const QString &rArg); + + /*! + * Returns a string representation of the error. + * + * The string has the following format: + * + * + * message (context::symbol, code): causing_error, causing_error + * + * + * If members are empty they are omitted: + * - Omit context, if empty + * - Omit symbol, if empty + * - Omit double colon with context and symbol, if both are empty + * - Omit code, if 0 + * - Omit bracket with context/symbol and code, if all are empty + * - Omit colon with causing errors, if no causing errors exist + */ + QString toString() const; + + private: + QString insertArgs(const QString &rMessage) const; + QString cleanMessage(const QString &rMessage); + + private: + int mCode; + QString mContext; + QString mMessage; + QString mSymbol; + QList mArgs; + QList mCausingErrors; + +#ifndef QT_NO_DATASTREAM + // Needs to be friend to stream objects + friend QDataStream &operator<<(QDataStream &rStream, + const LogError &rLogError); + friend QDataStream &operator>>(QDataStream &rStream, + LogError &rLogError); +#endif // QT_NO_DATASTREAM + }; + + + /************************************************************************** + * Operators, Helper + **************************************************************************/ + +#ifndef QT_NO_DATASTREAM + /*! + * \relates LogError + * + * Writes the given error \a rLogError to the given stream \a rStream, + * and returns a reference to the stream. + */ + QDataStream &operator<<(QDataStream &rStream, + const LogError &rLogError); + + /*! + * \relates LogError + * + * Reads an error from the given stream \a rStream into the given + * error \a rLogError, and returns a reference to the stream. + */ + QDataStream &operator>>(QDataStream &rStream, + LogError &rLogError); +#endif // QT_NO_DATASTREAM + +#ifndef QT_NO_DEBUG_STREAM + /*! + * \relates LogError + * + * Writes all object member variables to the given debug stream \a debug and + * returns the stream. + * + * + * %LogError(code:7 context:"Log4Qt::FileAppender" + * message:"Unable to open file '%1' for appender '%2'" + * symbol:"APPENDER_OPENING_FILE_ERROR" + * args:(QVariant(QString, "G:\logs\client.log") , QVariant(QString, "Client FileAppender") ) + * translatedMessage: "Unable to open file '%1' for appender '%2'" ) + * + * + * \sa QDebug + */ + QDebug operator<<(QDebug debug, + const LogError &rLogError); +#endif // QT_NO_DEBUG_STREAM + + + /************************************************************************** + * Inline + **************************************************************************/ + + inline int LogError::code() const + { return mCode; } + + inline QString LogError::context() const + { return mContext; } + + inline QString LogError::message() const + { return mMessage; } + + inline QString LogError::symbol() const + { return mSymbol; } + + inline void LogError::setCode(int code) + { mCode = code; } + + inline void LogError::setContext(const QString &rContext) + { mContext = rContext; } + + inline void LogError::setMessage(const QString &rMessage) + { mMessage = cleanMessage(rMessage); } + + inline void LogError::setSymbol(const QString &rSymbol) + { mSymbol = rSymbol; } + + inline LogError &LogError::addArg(const QVariant &rArg) + { mArgs << rArg; return *this; } + + inline LogError &LogError::addArg(int arg) + { mArgs << QVariant(arg); return *this; } + + inline LogError &LogError::addArg(const QString &rArg) + { mArgs << QVariant(rArg); return *this; } + + inline LogError &LogError::addCausingError(const LogError &rLogError) + { mCausingErrors << rLogError; return *this; } + + inline QList LogError::args() const + { return mArgs; } + + inline void LogError::clearArgs() + { mArgs.clear(); } + + inline void LogError::clearCausingErrors() + { mCausingErrors.clear(); } + + inline QList LogError::causingErrors() const + { return mCausingErrors; } + + inline bool LogError::isEmpty() const + { return mCode || !mMessage.isEmpty(); } + + inline QString LogError::messageWithArgs() const + { return insertArgs(message()); } + + inline QString LogError::translatedMessageWithArgs() const + { return insertArgs(translatedMessage()); } + + inline LogError &LogError::operator<<(const QVariant &rArg) + { return addArg(rArg); } + + inline LogError &LogError::operator<<(int arg) + { return addArg(arg); } + + inline LogError &LogError::operator<<(const QString &rArg) + { return addArg(rArg); } + + +} // namespace Log4Qt + + +Q_DECLARE_METATYPE(Log4Qt::LogError) +Q_DECLARE_TYPEINFO(Log4Qt::LogError, Q_MOVABLE_TYPE); + + +#endif // LOG4QT_ERROR_H diff --git a/src/log4qt/log4qt/helpers/logobject.cpp b/src/log4qt/log4qt/helpers/logobject.cpp new file mode 100644 index 0000000..44f1121 --- /dev/null +++ b/src/log4qt/log4qt/helpers/logobject.cpp @@ -0,0 +1,74 @@ +/****************************************************************************** + * + * package: Log4Qt + * file: logobject.cpp + * created: September 2007 + * author: Martin Heinrich + * + * + * Copyright 2007 Martin Heinrich + * + * 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. + * + ******************************************************************************/ + + +/****************************************************************************** + * Dependencies + ******************************************************************************/ + + +#include "log4qt/helpers/logobject.h" + +#include + + + +namespace Log4Qt +{ + + + /************************************************************************** + * Declarations + **************************************************************************/ + + + + /************************************************************************** + * C helper functions + **************************************************************************/ + + + + /************************************************************************** + * Class implementation: LogObject + **************************************************************************/ + + + + /************************************************************************** + * Implementation: Operators, Helper + **************************************************************************/ + + +#ifndef QT_NO_DEBUG_STREAM + QDebug operator<<(QDebug debug, + const LogObject &rLogObject) + { + return rLogObject.debug(debug); + } +#endif // QT_NO_DEBUG_STREAM + + + +} // namespace Log4Qt diff --git a/src/log4qt/log4qt/helpers/logobject.h b/src/log4qt/log4qt/helpers/logobject.h new file mode 100644 index 0000000..1c4efaf --- /dev/null +++ b/src/log4qt/log4qt/helpers/logobject.h @@ -0,0 +1,218 @@ +/****************************************************************************** + * + * package: Log4Qt + * file: logobject.h + * created: September 2007 + * author: Martin Heinrich + * + * + * changes: Sep 2008, Martin Heinrich: + * - Replaced usage of q_atomic_increment and q_atomic_decrement + * with QAtomicInt. + * Feb 2009, Martin Heinrich + * - Fixed a problem where the pParent parameter of the constructor + * was not passed on to the QObject constructor + * + * + * Copyright 2007 - 2009 Martin Heinrich + * + * 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. + * + ******************************************************************************/ + +#ifndef LOG4QT_LOGOBJECT_H +#define LOG4QT_LOGOBJECT_H + +#include "ukui-logmacros.h" + +/****************************************************************************** + * Dependencies + ******************************************************************************/ + +#include + +#include "log4qt/helpers/classlogger.h" +#if QT_VERSION >= QT_VERSION_CHECK(4, 4, 0) +# include +# ifndef Q_ATOMIC_INT_REFERENCE_COUNTING_IS_ALWAYS_NATIVE +# warning "QAtomicInt reference counting is not native. The class Log4Qt::LogObject is not thread-safe." +# endif +#endif + + +namespace Log4Qt +{ + + class Logger; + + /*! + * \brief The class LogObject is the common base class for many classes + * in the package. + * + * The class inherits QObject to allow its subclass to be accessed using + * the Qt property system. + * + * LogObject objects provide a reference counter. A reference to the + * object is established by calling retain() and freed by calling + * release(). The object will delete itself when the reference counter + * is decremented to 0. + * + * A class specific logger can be accessed over logger(). + * + * The class also implements generic streaming to QDebug. Streaming an + * object to QDebug will invoke debug() to create class specific output. + * + * \note All the functions declared in this class are thread-safe. + * + * \sa \ref Ownership "Object ownership", + * LOG4QT_DECLARE_QCLASS_LOGGER + */ + class LIBUKUILOG4QT_EXPORT LogObject : public QObject + { + Q_OBJECT + + public: + /*! + * Creates a LogObject which is a child of \a pObject. + */ + LogObject(QObject *pObject = 0); + + /*! + * Destroys the LogObject. + */ + virtual ~LogObject(); + + private: + LogObject(const LogObject &rOther); // Not implemented + LogObject &operator=(const LogObject &rOther); // Not implemented + + public: + /*! + * Returns the value of the reference counter. + */ + int referenceCount() const; + + /*! + * Decrements the reference count of the object. If the reference count + * count reaches zero and the object does not have a parent the object + * is deleted. + */ + void release(); + + /*! + * Increments the reference count of the object. + */ + void retain(); + + protected: + #ifndef QT_NO_DEBUG_STREAM + /*! + * Writes all object member variables to the given debug stream + * \a rDebug and returns the stream. + * + * The member function is used by + * QDebug operator<<(QDebug debug, const LogObject &rLogObject) to + * generate class specific output. + * + * \sa QDebug operator<<(QDebug debug, const LogObject &rLogObject) + */ + virtual QDebug debug(QDebug &rDebug) const = 0; + + // Needs to be friend to access internal data + friend QDebug operator<<(QDebug debug, + const LogObject &rLogObject); + #endif // QT_NO_DEBUG_STREAM + + /*! + * Returns a pointer to a Logger named after of the object. + * + * \sa Logger::logger(const char *pName) + */ + Logger* logger() const; + + private: +#if QT_VERSION < QT_VERSION_CHECK(4, 4, 0) + volatile int mReferenceCount; +#else + mutable QAtomicInt mReferenceCount; +#endif + mutable ClassLogger mLog4QtClassLogger; + }; + + + /************************************************************************** + * Operators, Helper + **************************************************************************/ + + #ifndef QT_NO_DEBUG_STREAM + /*! + * \relates LogObject + * + * Writes all object member variables to the given debug stream \a debug + * and returns the stream. + * + * To handle sub-classing the function uses the virtual member function + * debug(). This allows each class to generate its own output. + * + * \sa QDebug, debug() + */ + QDebug operator<<(QDebug debug, + const LogObject &rLogObject); + #endif + + + /************************************************************************** + * Inline + **************************************************************************/ + + inline LogObject::LogObject(QObject *pParent) : + QObject(pParent), + mReferenceCount() + {} + + inline LogObject::~LogObject() + {} + + inline int LogObject::referenceCount() const +#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0) + { return mReferenceCount; } +#else + { return mReferenceCount.loadAcquire(); } +#endif + + inline void LogObject::release() +#if QT_VERSION < QT_VERSION_CHECK(4, 4, 0) + { if ((q_atomic_decrement(&mReferenceCount) == 0) && !parent()) + delete(this); } +#else + { if (!mReferenceCount.deref()) + delete(this); } +#endif + + inline void LogObject::retain() +#if QT_VERSION < QT_VERSION_CHECK(4, 4, 0) + { q_atomic_increment(&mReferenceCount); } +#else + { mReferenceCount.ref(); } +#endif + + inline Logger *LogObject::logger() const + { return mLog4QtClassLogger.logger(this); } + +} // namespace Log4Qt + + +// Q_DECLARE_TYPEINFO(Log4Qt::LogObject, Q_COMPLEX_TYPE); // Use default + + +#endif // LOG4QT_LOGOBJECT_H diff --git a/src/log4qt/log4qt/helpers/logobjectptr.cpp b/src/log4qt/log4qt/helpers/logobjectptr.cpp new file mode 100644 index 0000000..8084a79 --- /dev/null +++ b/src/log4qt/log4qt/helpers/logobjectptr.cpp @@ -0,0 +1,65 @@ +/****************************************************************************** + * + * package: Log4Qt + * file: logobjectptr.cpp + * created: September 2007 + * author: Martin Heinrich + * + * + * Copyright 2007 Martin Heinrich + * + * 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. + * + ******************************************************************************/ + + +/****************************************************************************** + * Dependencies + ******************************************************************************/ + + +#include "log4qt/helpers/logobjectptr.h" + +#include + + + +namespace Log4Qt +{ + + + /************************************************************************** + * Declarations + **************************************************************************/ + + + + /************************************************************************** + * C helper functions + **************************************************************************/ + + + + /************************************************************************** + * Class implementation: LogObjectPtr + **************************************************************************/ + + + + /************************************************************************** + * Implementation: Operators, Helper + **************************************************************************/ + + + +} // namespace Log4Qt diff --git a/src/log4qt/log4qt/helpers/logobjectptr.h b/src/log4qt/log4qt/helpers/logobjectptr.h new file mode 100644 index 0000000..7b86508 --- /dev/null +++ b/src/log4qt/log4qt/helpers/logobjectptr.h @@ -0,0 +1,188 @@ +/****************************************************************************** + * + * package: Log4Qt + * file: logobjectptr.h + * created: September 2007 + * author: Martin Heinrich + * + * + * Copyright 2007 Martin Heinrich + * + * 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. + * + ******************************************************************************/ + +#ifndef LOG4QT_LOGOBJECTPTR_H +#define LOG4QT_LOGOBJECTPTR_H + +#include "ukui-logmacros.h" + +/****************************************************************************** + * Dependencies + ******************************************************************************/ + +#include "log4qt/helpers/logobject.h" + +namespace Log4Qt +{ + /*! + * \brief The class LogObjectPtr implements automatic reference counting + * for LogObject objects. + */ + template + class LIBUKUILOG4QT_EXPORT LogObjectPtr + { + public: + /*! + * Constructs a 0 LogObject pointer. + */ + LogObjectPtr(); + + /*! + * Constructs a LogObject pointer that points to the same object then + * \a rOther. The reference counter of the object is incremented by + * one. + */ + LogObjectPtr(const LogObjectPtr &rOther); + + /*! + * Constructs a LogObject pointer that points to the object + * \a LogObject. The reference counter of the object is incremented by + * one. + */ + LogObjectPtr(T *pLogObject); + + /*! + * Assignment operator. Sets the LogObject pointer to point to the + * same object that \a rOther points to. The reference counter of the + * object the LogObjectPtr pointed to before the assignment is + * decremented by one. The reference counter of the object \a rOther + * is pointing to is incremented by one. + */ + LogObjectPtr &operator=(const LogObjectPtr &rOther); + + /*! + * Destructs the object. The reference counter of the object the + * LogObjectPtr points to is decremented by one. + */ + ~LogObjectPtr(); + + /*! + * Assignment operator. Sets the LogObject pointer to point to the + * object \a pLogObject. The reference counter of the object the + * LogObjectPtr pointed to before the assignment is decremented by + * one. The reference counter of the object \a pLogObject is pointing + * to is incremented by one. + */ + LogObjectPtr &operator=(T *pLogObject); + + /*! + * Arrow operator. Returns the LogObject the object points to. + */ + T *operator->() const; + + /*! + * Dereference operator. Returns a pointer to the LogObject the + * object points to. + */ + T &operator*() const; + + /*! + * Cast operator. Cast the object to the LogObject the object points + * to. + */ + operator T*() const; + + private: + void retain() const; + void release() const; + + private: + T *mpLogObject; + }; + + + /************************************************************************** + * Operators, Helper + **************************************************************************/ + + + /************************************************************************** + * Inline + **************************************************************************/ + + template + inline LogObjectPtr::LogObjectPtr() : + mpLogObject(0) + {} + + template + inline LogObjectPtr::LogObjectPtr(const LogObjectPtr &rOther) : + mpLogObject(rOther.mpLogObject) + { retain(); } + + template + inline LogObjectPtr::LogObjectPtr(T *pLogObject) : + mpLogObject(pLogObject) + { retain(); } + + template + inline LogObjectPtr &LogObjectPtr::operator=(const LogObjectPtr &rOther) + { rOther.retain(); + release(); + mpLogObject = rOther.mpLogObject; + return *this; } + + template + inline LogObjectPtr::~LogObjectPtr() + { release(); } + + template + inline LogObjectPtr &LogObjectPtr::operator=(T *pLogObject) + { if (pLogObject) + reinterpret_cast(pLogObject)->retain(); + release(); + mpLogObject = pLogObject; + return *this; } + + template + inline T *LogObjectPtr::operator->() const + { return mpLogObject; } + + template + inline T &LogObjectPtr::operator*() const + { return *mpLogObject; } + + template + inline LogObjectPtr::operator T*() const + { return mpLogObject; } + + template + inline void LogObjectPtr::retain() const + { if (mpLogObject) + reinterpret_cast(mpLogObject)->retain(); } + + template + inline void LogObjectPtr::release() const + { + if (mpLogObject) + reinterpret_cast(mpLogObject)->release(); + } + +} // namespace Log4Qt + + +//Q_DECLARE_TYPEINFO(Log4Qt::LogObjectPtr, Q_MOVABLE_TYPE); // Declare within T + + +#endif // LOG4QT_LOGOBJECTPTR_H diff --git a/src/log4qt/log4qt/helpers/optionconverter.cpp b/src/log4qt/log4qt/helpers/optionconverter.cpp new file mode 100644 index 0000000..15fb645 --- /dev/null +++ b/src/log4qt/log4qt/helpers/optionconverter.cpp @@ -0,0 +1,315 @@ +/****************************************************************************** + * + * package: Log4Qt + * file: optionconverter.cpp + * created: September 2007 + * author: Martin Heinrich + * + * + * changes Feb 2009, Martin Heinrich + * - Fixed a problem were OptionConverter::toBoolean would not + * return the default value, if the conversion fails. + * + * + * Copyright 2007 - 2009 Martin Heinrich + * + * 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. + * + ******************************************************************************/ + + +/****************************************************************************** + * Dependencies + ******************************************************************************/ + + +#include "log4qt/helpers/optionconverter.h" + +#include +#include "log4qt/helpers/logerror.h" +#include "log4qt/helpers/properties.h" +#include "log4qt/logger.h" +#include "log4qt/consoleappender.h" + + + +namespace Log4Qt +{ + + + /************************************************************************** + * Declarations + **************************************************************************/ + + + + /************************************************************************** + * C helper functions + **************************************************************************/ + + + LOG4QT_DECLARE_STATIC_LOGGER(logger, Log4Qt::OptionConverter) + + + + /************************************************************************** + * Class implementation: OptionConverter + **************************************************************************/ + + + QString OptionConverter::findAndSubst(const Properties &rProperties, + const QString &rKey) + { + QString value = rProperties.property(rKey); + if (value.isNull()) + return value; + + const QString begin_subst = QLatin1String("${"); + const QString end_subst = QLatin1String("}"); + const int begin_length = begin_subst.length(); + const int end_length = end_subst.length(); + + // Don't return a null string, the null string indicates that the + // property key does not exist. + QString result = QLatin1String(""); + + int i = 0; + int begin; + int end; + while (i < value.length()) + { + begin = value.indexOf(begin_subst, i); + if (begin == -1) + { + result += value.mid(i); + i = value.length(); + } + else + { + result += value.mid(i, begin - i); + end = value.indexOf(end_subst, i + begin_length); + if (end == -1) + { + LogError e = LOG4QT_ERROR(QT_TR_NOOP("Missing closing bracket for opening bracket at %1. Invalid subsitution in value %2."), + CONFIGURATOR_INVALID_SUBSTITUTION_ERROR, + "Log4Qt::OptionConverter"); + e << begin << value; + logger()->error(e); + return result; + } + else + { + result += findAndSubst(rProperties, value.mid(begin + begin_length, end - begin - end_length - 1)); + i = end + end_length; + } + } + } + return result; + } + + + QString OptionConverter::classNameJavaToCpp(const QString &rClassName) + { + const QLatin1String java_class_delimiter("."); + const QLatin1String cpp_class_delimiter("::"); + + QString result = rClassName; + return result.replace(java_class_delimiter, cpp_class_delimiter); + } + + + bool OptionConverter::toBoolean(const QString &rOption, + bool *p_ok) + { + const QLatin1String str_true("true"); + const QLatin1String str_enabled("enabled"); + const QLatin1String str_one("1"); + const QLatin1String str_false("false"); + const QLatin1String str_disabled("disabled"); + const QLatin1String str_zero("0"); + + if (p_ok) + *p_ok = true; + QString s = rOption.trimmed().toLower(); + if (s == str_true || s == str_enabled || s == str_one) + return true; + if (s == str_false || s == str_disabled || s == str_zero) + return false; + + if (p_ok) + *p_ok = false; + LogError e = LOG4QT_ERROR(QT_TR_NOOP("Invalid option string '%1' for a boolean"), + CONFIGURATOR_INVALID_OPTION_ERROR, + "Log4Qt::OptionConverter"); + e << rOption; + logger()->error(e); + return false; + } + + + bool OptionConverter::toBoolean(const QString &rOption, + bool default_value) + { + bool ok; + bool result = toBoolean(rOption, &ok); + if (ok) + return result; + else + return default_value; + } + + qint64 OptionConverter::toFileSize(const QString &rOption, + bool *p_ok) + { + // - Search for unit + // - Convert characters befor unit to int + // - Error, if + // - the conversion failed + // - the value < 0 + // - there is text after the unit characters + + if (p_ok) + *p_ok = false; + QString s = rOption.trimmed().toLower(); + qint64 f = 1; + int i; + i = s.indexOf(QLatin1String("kb")); + if (i >= 0) + f = 1024; + else + { + i = s.indexOf(QLatin1String("mb")); + if (i >= 0) + f = 1024 * 1024; + else + { + i = s.indexOf(QLatin1String("gb")); + if (i >= 0) + f = 1024 * 1024 * 1024; + } + } + if (i < 0) + i = s.length(); + bool ok; + qint64 value = s.left(i).toLongLong(&ok); + if (!ok || value < 0 || s.length() > i + 2) + { + LogError e = LOG4QT_ERROR(QT_TR_NOOP("Invalid option string '%1' for a file size"), + CONFIGURATOR_INVALID_OPTION_ERROR, + "Log4Qt::OptionConverter"); + e << rOption; + logger()->error(e); + return 0; + } + if (p_ok) + *p_ok = true; + return value * f; + } + + + int OptionConverter::toInt(const QString &rOption, + bool *p_ok) + { + int value = rOption.trimmed().toInt(p_ok); + if (*p_ok) + return value; + + LogError e = LOG4QT_ERROR(QT_TR_NOOP("Invalid option string '%1' for an integer"), + CONFIGURATOR_INVALID_OPTION_ERROR, + "Log4Qt::OptionConverter"); + e << rOption; + logger()->error(e); + return 0; + } + + qint64 OptionConverter::toQInt64(const QString &rOption, + bool *p_ok) + { + int value = rOption.trimmed().toLongLong(p_ok); + if (*p_ok) + return value; + + LogError e = LOG4QT_ERROR(QT_TR_NOOP("Invalid option string '%1' for an qint64"), + CONFIGURATOR_INVALID_OPTION_ERROR, + "Log4Qt::OptionConverter"); + e << rOption; + logger()->error(e); + return 0; + } + + Level OptionConverter::toLevel(const QString &rOption, + bool *p_ok) + { + bool ok; + Level level = Level::fromString(rOption.toUpper().trimmed(), &ok); + if (p_ok) + *p_ok = ok; + if (ok) + return level; + + LogError e = LOG4QT_ERROR(QT_TR_NOOP("Invalid option string '%1' for a level"), + CONFIGURATOR_INVALID_OPTION_ERROR, + "Log4Qt::OptionConverter"); + e << rOption; + logger()->error(e); + return level; + } + + + Level OptionConverter::toLevel(const QString &rOption, + const Level &rDefaultValue) + { + bool ok; + Level result = toLevel(rOption, &ok); + if (ok) + return result; + else + return rDefaultValue; + } + + + int OptionConverter::toTarget(const QString &rOption, + bool *p_ok) + { + const QLatin1String java_stdout("system.out"); + const QLatin1String cpp_stdout("stdout_target"); + const QLatin1String java_stderr("system.err"); + const QLatin1String cpp_stderr("stderr_target"); + + if (p_ok) + *p_ok = true; + QString s = rOption.trimmed().toLower(); + if (s == java_stdout || s == cpp_stdout) + return ConsoleAppender::STDOUT_TARGET; + if (s == java_stderr || s == cpp_stderr) + return ConsoleAppender::STDERR_TARGET; + + if (p_ok) + *p_ok = false; + LogError e = LOG4QT_ERROR(QT_TR_NOOP("Invalid option string '%1' for a target"), + CONFIGURATOR_INVALID_OPTION_ERROR, + "Log4Qt::OptionConverter"); + e << rOption; + logger()->error(e); + return ConsoleAppender::STDOUT_TARGET; + } + + + + /************************************************************************** + * Implementation: Operators, Helper + **************************************************************************/ + + + +} // namespace Log4Qt diff --git a/src/log4qt/log4qt/helpers/optionconverter.h b/src/log4qt/log4qt/helpers/optionconverter.h new file mode 100644 index 0000000..c29cbda --- /dev/null +++ b/src/log4qt/log4qt/helpers/optionconverter.h @@ -0,0 +1,151 @@ +/****************************************************************************** + * + * package: Log4Qt + * file: optionconverter.h + * created: September 2007 + * author: Martin Heinrich + * + * + * Copyright 2007 Martin Heinrich + * + * 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. + * + ******************************************************************************/ + +#ifndef LOG4QT_OPTIONCONVERTER_H +#define LOG4QT_OPTIONCONVERTER_H + +#include "ukui-logmacros.h" + +/****************************************************************************** + * Dependencies + ******************************************************************************/ + +#include +#include "log4qt/level.h" + +namespace Log4Qt +{ + class Properties; + + /*! + * \brief The class OptionConverter provides functions to convert strings + * to property values. + */ + class LIBUKUILOG4QT_EXPORT OptionConverter + { + private: + OptionConverter(); + OptionConverter(const OptionConverter &rOther); // Not implemented + // virtual ~OptionConverter(); // Use compiler default + OptionConverter &operator=(const OptionConverter &rOther); // Not implemented + + public: + static QString findAndSubst(const Properties &rProperties, + const QString &rKey); + + /*! + * Returns the JAVA class name \a rClassName as C++ class name by + * replacing all . characters with ::. + */ + static QString classNameJavaToCpp(const QString &rClassName); + + /*! + * Converts the option \a rOption to a boolean value. Valid strings + * for true are "true", "enabled" and "1". Valid strings + * for false are "false", "disabled" and "0". If the conversion is + * successful, the target is returned and \a p_ok is set to true. + * Otherwise an error is written to the log, \a p_ok is set to false + * and false is returned. + */ + static bool toBoolean(const QString &rOption, + bool *p_ok = 0); + + static bool toBoolean(const QString &rOption, + bool default_value); + + /*! + * Converts the option string \a rOption to a file size. The string can + * be a positive integer followed by an optional unit suffix "KB", "MB" + * or "GB". If a unit suffix is specified the the integer is + * interpreted as kilobytes, megabytes or gigabytes. If the conversion + * is successful, the size is returned and \a p_ok is set to true. + * Otherwise an error is written to the log, \a p_ok is set to false + * and 0 is returned. + */ + static qint64 toFileSize(const QString &rOption, + bool *p_ok = 0); + + /*! + * Converts the option \a rOption to a integer value using + * QString::toInt(). If the conversion is successful, the integer is + * returned and \a p_ok is set to true. Otherwise an error is written + * to the log, \a p_ok is set to false and 0 is returned. + */ + static int toInt(const QString &rOption, + bool *p_ok = 0); + + /*! + * Converts the option \a rOption to a qint64 value using + * QString::toLongLong(). If the conversion is successful, the qint64 is + * returned and \a p_ok is set to true. Otherwise an error is written + * to the log, \a p_ok is set to false and 0 is returned. + */ + static qint64 toQInt64(const QString &rOption, + bool *p_ok = 0); + + /*! + * Converts the option \a rOption to a level value using + * Level::fromString(). If the conversion is successful, the level + * is returned and \a p_ok is set to true. Otherwise an error is + * written to the log, \a p_ok is set to false and a level with + * the value Level::NULL_INT is returned. + * + * \sa Level::fromString() + */ + static Level toLevel(const QString &rOption, + bool *p_ok = 0); + + static Level toLevel(const QString &rOption, + const Level &rDefaultValue); + + /*! + * Converts the option \a rOption to a ConsoleAppender::Target value. + * Valid strings for \a rOption are "System.out", "STDOUT_TARGET", + * "System.err" and "STDERR_TARGET". If the conversion is successful, + * the target is returned and \a p_ok is set to true. Otherwise an + * error is written to the log, \a p_ok is set to false and + * ConsoleAppender::STDOUT_TARGET is returned. + */ + static int toTarget(const QString &rOption, + bool *p_ok = 0); + }; + + + /************************************************************************** + * Operators, Helper + **************************************************************************/ + + + /************************************************************************** + * Inline + **************************************************************************/ + + +} // namespace Log4Qt + + +Q_DECLARE_TYPEINFO(Log4Qt::OptionConverter, Q_MOVABLE_TYPE); + + +#endif // LOG4QT_OPTIONCONVERTER_H diff --git a/src/log4qt/log4qt/helpers/patternformatter.cpp b/src/log4qt/log4qt/helpers/patternformatter.cpp new file mode 100644 index 0000000..60f5271 --- /dev/null +++ b/src/log4qt/log4qt/helpers/patternformatter.cpp @@ -0,0 +1,893 @@ +/****************************************************************************** + * + * package: Log4Qt + * file: patternformatter.cpp + * created: September 2007 + * author: Martin Heinrich + * + * + * changes Feb 2009, Martin Heinrich + * - Fixed VS 2008 unreferenced formal parameter warning by using + * Q_UNUSED in LiteralPatternConverter::convert. + * + * + * Copyright 2007 - 2009 Martin Heinrich + * + * 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. + * + ******************************************************************************/ + + + +/****************************************************************************** + * Dependencies + ******************************************************************************/ + +#include "log4qt/helpers/patternformatter.h" + +#include +#include +#include +#include "log4qt/helpers/datetime.h" +#include "log4qt/helpers/logerror.h" +#include "log4qt/layout.h" +#include "log4qt/logger.h" +#include "log4qt/loggingevent.h" + + + +namespace Log4Qt +{ + + + /************************************************************************** + *Declarations + **************************************************************************/ + + + /*! + * \brief The class FormattingInfo stores the formatting modifier for a + * pattern converter. + * + * \sa PatternConverter + */ + class FormattingInfo + { + public: + FormattingInfo() + { clear(); } + // FormattingInfo(const FormattingInfo &rOther); // Use compiler default + // virtual ~FormattingInfo(); // Use compiler default + // FormattingInfo &operator=(const FormattingInfo &rOther); // Use compiler default + + void clear(); + static QString intToString(int i); + + public: + int mMinLength; + int mMaxLength; + bool mLeftAligned; + }; + + + /*! + * \brief The class PatternConverter is the abstract base class for all + * pattern converters. + * + * PatternConverter handles the minimum and maximum modifier for a + * conversion character. The actual conversion is by calling the + * convert() member function of the derived class. + * + * \sa PatternLayout::format() + */ + class PatternConverter + { + public: + PatternConverter(const FormattingInfo &rFormattingInfo = FormattingInfo()) : + mFormattingInfo(rFormattingInfo) + {}; + virtual ~PatternConverter() + {}; + private: + PatternConverter(const PatternConverter &rOther); // Not implemented + PatternConverter &operator=(const PatternConverter &rOther); // Not implemented + + public: + void format(QString &rFormat, const LoggingEvent &rLoggingEvent) const; + + protected: + virtual QString convert(const LoggingEvent &rLoggingEvent) const = 0; + #ifndef QT_NO_DEBUG_STREAM + virtual QDebug debug(QDebug &rDebug) const = 0; + friend QDebug operator<<(QDebug, const PatternConverter &rPatternConverter); + #endif + + protected: + FormattingInfo mFormattingInfo; + }; + + + /*! + * \brief The class BasicPatternConverter converts several members of a + * LoggingEvent to a string. + * + * BasicPatternConverter is used by PatternLayout to convert members that + * do not reuquire additional formatting to a string as part of formatting + * the LoggingEvent. It handles the following conversion characters: + * 'm', 'p', 't', 'x' + * + * \sa PatternLayout::format() + * \sa PatternConverter::format() + */ + class BasicPatternConverter : public PatternConverter + { + public: + enum Type { + MESSAGE_CONVERTER, + NDC_CONVERTER, + LEVEL_CONVERTER, + THREAD_CONVERTER, + }; + + public: + BasicPatternConverter(const FormattingInfo &rFormattingInfo, + Type type) : + PatternConverter(rFormattingInfo), + mType(type) + {}; + // virtual ~BasicPatternConverter(); // Use compiler default + private: + BasicPatternConverter(const BasicPatternConverter &rOther); // Not implemented + BasicPatternConverter &operator=(const BasicPatternConverter &rOther); // Not implemented + + protected: + virtual QString convert(const LoggingEvent &rLoggingEvent) const; + #ifndef QT_NO_DEBUG_STREAM + virtual QDebug debug(QDebug &rDebug) const; + #endif + + private: + Type mType; + }; + + + /*! + * \brief The class DatePatternConverter converts the time stamp of a + * LoggingEvent to a string. + * + * DatePatternConverter is used by PatternLayout to convert the time stamp + * of a LoggingEvent to a string as part of formatting the LoggingEvent. + * It handles the 'd' and 'r' conversion character. + * + * \sa PatternLayout::format() + * \sa PatternConverter::format() + */ + class DatePatternConverter : public PatternConverter + { + public: + DatePatternConverter(const FormattingInfo &rFormattingInfo, + const QString &rFormat) : + PatternConverter(rFormattingInfo), + mFormat(rFormat) + {}; + // virtual ~DatePatternConverter(); // Use compiler default + private: + DatePatternConverter(const DatePatternConverter &rOther); // Not implemented + DatePatternConverter &operator=(const DatePatternConverter &rOther); // Not implemented + + protected: + virtual QString convert(const LoggingEvent &rLoggingEvent) const; + #ifndef QT_NO_DEBUG_STREAM + virtual QDebug debug(QDebug &rDebug) const; + #endif + + private: + QString mFormat; + }; + + + /*! + * \brief The class LiteralPatternConverter provides string literals. + * + * LiteralPatternConverter is used by PatternLayout to embed string + * literals as part of formatting the LoggingEvent. It handles string + * literals and the 'n' conversion character. + * + * \sa PatternLayout::format() + * \sa PatternConverter::format() + */ + class LiteralPatternConverter : public PatternConverter + { + public: + LiteralPatternConverter(const QString &rLiteral) : + PatternConverter(), + mLiteral(rLiteral) + {}; + // virtual ~LiteralPatternConverter(); // Use compiler default + private: + LiteralPatternConverter(const LiteralPatternConverter &rOther); // Not implemented + LiteralPatternConverter &operator=(const LiteralPatternConverter &rOther); // Not implemented + + protected: + virtual QString convert(const LoggingEvent &rLoggingEvent) const; + #ifndef QT_NO_DEBUG_STREAM + virtual QDebug debug(QDebug &rDebug) const; + #endif + + private: + QString mLiteral; + }; + + + /*! + * \brief The class LoggerPatternConverter converts the Logger name of a + * LoggingEvent to a string. + * + * LoggerPatternConverter is used by PatternLayout to convert the Logger + * name of a LoggingEvent to a string as part of formatting the + * LoggingEvent. It handles the 'c' conversion character. + * + * \sa PatternLayout::format() + * \sa PatternConverter::format() + */ + class LoggerPatternConverter : public PatternConverter + { + public: + LoggerPatternConverter(const FormattingInfo &rFormattingInfo, + int precision) : + PatternConverter(rFormattingInfo), + mPrecision(precision) + {}; + // virtual ~LoggerPatternConverter(); // Use compiler default + private: + LoggerPatternConverter(const LoggerPatternConverter &rOther); // Not implemented + LoggerPatternConverter &operator=(const LoggerPatternConverter &rOther); // Not implemented + + protected: + virtual QString convert(const LoggingEvent &rLoggingEvent) const; + #ifndef QT_NO_DEBUG_STREAM + virtual QDebug debug(QDebug &rDebug) const; + #endif + + private: + int mPrecision; + }; + + + + /*! + * \brief The class MDCPatternConverter converts the MDC data of a + * LoggingEvent to a string. + * + * MDCPatternConverter is used by PatternLayout to convert the MDC data of + * a LoggingEvent to a string as part of formatting the LoggingEvent. It + * handles the 'X' conversion character. + * + * \sa PatternLayout::format() + * \sa PatternConverter::format() + */ + class MDCPatternConverter : public PatternConverter + { + public: + MDCPatternConverter(const FormattingInfo &rFormattingInfo, + const QString &rKey) : + PatternConverter(rFormattingInfo), + mKey(rKey) + {}; + // virtual ~MDCPatternConverter(); // Use compiler default + private: + MDCPatternConverter(const MDCPatternConverter &rOther); // Not implemented + MDCPatternConverter &operator=(const MDCPatternConverter &rOther); // Not implemented + + protected: + virtual QString convert(const LoggingEvent &rLoggingEvent) const; + #ifndef QT_NO_DEBUG_STREAM + virtual QDebug debug(QDebug &rDebug) const; + #endif + + private: + QString mKey; + }; + + + #ifndef QT_NO_DEBUG_STREAM + QDebug operator<<(QDebug, const FormattingInfo &rFormattingInfo); + #endif + + + #ifndef QT_NO_DEBUG_STREAM + QDebug operator<<(QDebug, const PatternConverter &rPatternConverter); + #endif + + + + /************************************************************************** + * C helper functions + **************************************************************************/ + + + LOG4QT_DECLARE_STATIC_LOGGER(logger, Log4Qt::PatternFormatter) + + + + /************************************************************************** + * Class implementation: PatternFormatter + **************************************************************************/ + + + PatternFormatter::PatternFormatter(const QString &rPattern) : + mIgnoreCharacters(QLatin1String("CFlLM")), + mConversionCharacters(QLatin1String("cdmprtxX")), + mOptionCharacters(QLatin1String("cd")), + mPattern(rPattern), + mPatternConverters() + { + parse(); + } + + + PatternFormatter::~PatternFormatter() + { + PatternConverter *p_converter; + Q_FOREACH(p_converter, mPatternConverters) + delete p_converter; + } + + + QString PatternFormatter::format(const LoggingEvent &rLoggingEvent) const + { + QString result; + PatternConverter *p_converter; + Q_FOREACH(p_converter, mPatternConverters) + p_converter->format(result, rLoggingEvent); + return result; + } + + + bool PatternFormatter::addDigit(const QChar &rDigit, + int &rValue) + { + if (!rDigit.isDigit()) + return false; + + int digit_value = rDigit.digitValue(); + if (rValue > (INT_MAX - digit_value) / 10) + rValue = INT_MAX; + else + rValue = rValue * 10 + digit_value; + return true; + } + + + void PatternFormatter::createConverter(const QChar &rChar, + const FormattingInfo &rFormattingInfo, + const QString &rOption) + { + Q_ASSERT_X(mConversionCharacters.indexOf(rChar) >= 0, "PatternFormatter::createConverter", "Unknown conversion character" ); + + LogError e("Creating Converter for character '%1' min %2, max %3, left %4 and option '%5'"); + e << QString(rChar) + << FormattingInfo::intToString(rFormattingInfo.mMinLength) + << FormattingInfo::intToString(rFormattingInfo.mMaxLength) + << rFormattingInfo.mLeftAligned + << rOption; + logger()->trace(e); + + switch (rChar.toLatin1()) + { + case 'c': + mPatternConverters << new LoggerPatternConverter(rFormattingInfo, + parseIntegerOption(rOption)); + break; + case 'd': + { + QString option = rOption; + if (rOption.isEmpty()) + option = QLatin1String("ISO8601"); + mPatternConverters << new DatePatternConverter(rFormattingInfo, + option); + break; + } + case 'm': + mPatternConverters << new BasicPatternConverter(rFormattingInfo, + BasicPatternConverter::MESSAGE_CONVERTER); + break; + case 'p': + mPatternConverters << new BasicPatternConverter(rFormattingInfo, + BasicPatternConverter::LEVEL_CONVERTER); + break; + case 'r': + mPatternConverters << new DatePatternConverter(rFormattingInfo, + QLatin1String("TIME_RELATIVE")); + break; + case 't': + mPatternConverters << new BasicPatternConverter(rFormattingInfo, + BasicPatternConverter::THREAD_CONVERTER); + break; + case 'x': + mPatternConverters << new BasicPatternConverter(rFormattingInfo, + BasicPatternConverter::NDC_CONVERTER); + break; + case 'X': + mPatternConverters << new MDCPatternConverter(rFormattingInfo, + rOption); + break; + default: + Q_ASSERT_X(false, "PatternFormatter::createConverter", "Unknown pattern character"); + } + } + + + void PatternFormatter::createLiteralConverter(const QString &rLiteral) + { + logger()->trace("Creating literal LiteralConverter with Literal '%1'", + rLiteral); + mPatternConverters << new LiteralPatternConverter(rLiteral); + } + + + void PatternFormatter::parse() + { + enum State { + LITERAL_STATE, + ESCAPE_STATE, + MIN_STATE, + DOT_STATE, + MAX_STATE, + CHARACTER_STATE, + POSSIBLEOPTION_STATE, + OPTION_STATE + }; + + int i = 0; + QChar c; + char ch; + State state = LITERAL_STATE; + FormattingInfo formatting_info; + QString literal; + int converter_start; + int option_start; + while (i < mPattern.length()) + { + // i points to the current character + // c contains the current character + // ch contains the Latin1 equivalent of the current character + // i is incremented at the end of the loop to consume the character + // continue is used to change state without consuming the character + + c = mPattern.at(i); + ch = c.toLatin1(); + switch (state) + { + case LITERAL_STATE: + if (ch == '%') + { + formatting_info.clear(); + converter_start = i; + state = ESCAPE_STATE; + } else + literal += c; + break; + case ESCAPE_STATE: + if (ch == '%') + { + literal += c; + state = LITERAL_STATE; + } + else if (ch == 'n') + { + literal += Layout::endOfLine(); + state = LITERAL_STATE; + } + else + { + if (!literal.isEmpty()) + { + createLiteralConverter(literal); + literal.clear(); + } + if (ch == '-') + formatting_info.mLeftAligned = true; + else if (c.isDigit()) + { + formatting_info.mMinLength = c.digitValue(); + state = MIN_STATE; + } + else if (ch == '.') + state = DOT_STATE; + else + { + state = CHARACTER_STATE; + continue; + } + } + break; + case MIN_STATE: + if (!addDigit(c, formatting_info.mMinLength)) + { + if (ch == '.') + state = DOT_STATE; + else + { + state = CHARACTER_STATE; + continue; + } + } + break; + case DOT_STATE: + if (c.isDigit()) + { + formatting_info.mMaxLength = c.digitValue(); + state = MAX_STATE; + } + else + { + LogError e = LOG4QT_ERROR(QT_TR_NOOP("Found character '%1' where digit was expected."), + LAYOUT_EXPECTED_DIGIT_ERROR, + "Log4Qt::PatternFormatter"); + e << QString(c); + logger()->error(e); + } + break; + case MAX_STATE: + if (!addDigit(c, formatting_info.mMaxLength)) + { + state = CHARACTER_STATE; + continue; + } + break; + case CHARACTER_STATE: + if (mIgnoreCharacters.indexOf(c) >= 0) + state = LITERAL_STATE; + else if (mOptionCharacters.indexOf(c) >= 0) + state = POSSIBLEOPTION_STATE; + else if (mConversionCharacters.indexOf(c) >= 0) + { + createConverter(c, formatting_info); + state = LITERAL_STATE; + } + else + { + logger()->warn("Invalid conversion character '%1' at %2 in pattern '%3'", + c, i, mPattern); + createLiteralConverter(mPattern.mid(converter_start, i - converter_start + 1)); + state = LITERAL_STATE; + } + break; + case POSSIBLEOPTION_STATE: + if (ch == '{') + { + option_start = i; + state = OPTION_STATE; + } + else + { + createConverter(mPattern.at(i - 1), + formatting_info); + state = LITERAL_STATE; + continue; + } + break; + case OPTION_STATE: + if (ch == '}') + { + createConverter(mPattern.at(option_start - 1), + formatting_info, + mPattern.mid(option_start + 1, i - option_start - 1)); + state = LITERAL_STATE; + } + break; + default: + Q_ASSERT_X(false, "PatternFormatter::parse()", "Unknown parsing state constant"); + state = LITERAL_STATE; + } + i++; + } + + if (state != LITERAL_STATE) + { + logger()->warn("Unexptected end of pattern '%1'", mPattern); + if (state == ESCAPE_STATE) + literal += c; + else + literal += mPattern.mid(converter_start); + } + + if (!literal.isEmpty()) + createLiteralConverter(literal); + } + + + int PatternFormatter::parseIntegerOption(const QString &rOption) + { + if (rOption.isEmpty()) + return 0; + + bool ok; + int result = rOption.toInt(&ok); + if (!ok) + { + LogError e = LOG4QT_ERROR(QT_TR_NOOP("Option '%1' cannot be converted into an integer"), + LAYOUT_OPTION_IS_NOT_INTEGER_ERROR, + "Log4Qt::PatterFormatter"); + e << rOption; + logger()->error(e); + } + if (result < 0) + { + LogError e = LOG4QT_ERROR(QT_TR_NOOP("Option %1 isn't a positive integer"), + LAYOUT_INTEGER_IS_NOT_POSITIVE_ERROR, + "Log4Qt::PatterFormatter"); + e << result; + logger()->error(e); + result = 0; + } + return result; + } + + + /************************************************************************** + * Class implementation: FormattingInfo + **************************************************************************/ + + + void FormattingInfo::clear() + { + mMinLength = 0; + mMaxLength = INT_MAX; + mLeftAligned = false; + }; + + + QString FormattingInfo::intToString(int i) + { + if (i == INT_MAX) + return QLatin1String("INT_MAX"); + else + return QString::number(i); + } + + + + /************************************************************************** + * Class implementation: PatternConverter + **************************************************************************/ + + + void PatternConverter::format(QString &rFormat, const LoggingEvent &rLoggingEvent) const + { + const QLatin1Char space(' '); + QString s = convert(rLoggingEvent); + + if (s.length() > mFormattingInfo.mMaxLength) + rFormat += s.left(mFormattingInfo.mMaxLength); + else if (mFormattingInfo.mLeftAligned) + rFormat += s.leftJustified(mFormattingInfo.mMinLength, space, false); + else + rFormat += s.rightJustified(mFormattingInfo.mMinLength, space, false); + } + + + + /************************************************************************** + * Class implementation: BasicPatternConverter + **************************************************************************/ + + + QString BasicPatternConverter::convert(const LoggingEvent &rLoggingEvent) const + { + switch (mType) + { + case MESSAGE_CONVERTER: + return rLoggingEvent.message(); + break; + case NDC_CONVERTER: + return rLoggingEvent.ndc(); + break; + case LEVEL_CONVERTER: + return rLoggingEvent.level().toString(); + break; + case THREAD_CONVERTER: + return rLoggingEvent.threadName(); + break; + default: + Q_ASSERT_X(false, "BasicPatternConverter::convert()", "Unkown type constant"); + return QString(); + } + } + + + QDebug BasicPatternConverter::debug(QDebug &rDebug) const + { + QString type; + switch (mType) + { + case MESSAGE_CONVERTER: + type = QLatin1String("MESSAGE_CONVERTER"); + break; + case NDC_CONVERTER: + type = QLatin1String("NDC_CONVERTER"); + break; + case LEVEL_CONVERTER: + type = QLatin1String("LEVEL_CONVERTER"); + break; + case THREAD_CONVERTER: + type = QLatin1String("THREAD_CONVERTER"); + break; + default: + Q_ASSERT_X(false, "BasicPatternConverter::debug()", "Unkown type constant"); + } + rDebug.nospace() << "BasicPatternConverter(" + << mFormattingInfo + << "type:" << type + << ")"; + return rDebug.space(); + } + + + + /************************************************************************** + * Class implementation: DatePatternConverter + **************************************************************************/ + + + QString DatePatternConverter::convert(const LoggingEvent &rLoggingEvent) const + { + return DateTime::fromMilliSeconds(rLoggingEvent.timeStamp()).toString(mFormat); + } + + + QDebug DatePatternConverter::debug(QDebug &rDebug) const + { + rDebug.nospace() << "DatePatternConverter(" + << mFormattingInfo + << "format:" << mFormat + << ")"; + return rDebug.space(); + } + + + + /************************************************************************** + * Class implementation: LiteralPatternConverter + **************************************************************************/ + + + QString LiteralPatternConverter::convert(const LoggingEvent &rLoggingEvent) const + { + Q_UNUSED(rLoggingEvent); + return mLiteral; + }; + + + QDebug LiteralPatternConverter::debug(QDebug &rDebug) const + { + rDebug.nospace() << "LiteralPatternConverter(" + << mFormattingInfo + << "literal:" << mLiteral + << ")"; + return rDebug.space(); + } + + + + /************************************************************************** + * Class implementation: LoggerPatternConverter + **************************************************************************/ + + + QString LoggerPatternConverter::convert(const LoggingEvent &rLoggingEvent) const + { + if (!rLoggingEvent.logger()) + return QString(); + QString name = rLoggingEvent.logger()->name(); + if (mPrecision <= 0 || (name.isEmpty())) + return name; + + const QString separator(QLatin1String("::")); + + int i = mPrecision; + int begin = name.length(); + while ((i > 0) && (begin >= 0)) + { + begin = name.lastIndexOf(separator, begin - name.length() - 1); + i--; + } + if (begin < 0) + begin = 0; + else + begin += 2; + return name.mid(begin); + } + + + QDebug LoggerPatternConverter::debug(QDebug &rDebug) const + { + rDebug.nospace() << "LoggerPatternConverter(" + << mFormattingInfo + << "precision:" << mPrecision + << ")"; + return rDebug.space(); + } + + + + /****************************************************************************** + * Class implementation: MDCPatternConverter + ******************************************************************************/ + + + QString MDCPatternConverter::convert(const LoggingEvent &rLoggingEvent) const + { + return rLoggingEvent.mdc().value(mKey); + }; + + + QDebug MDCPatternConverter::debug(QDebug &rDebug) const + { + rDebug.nospace() << "MDCPatternConverter(" + << mFormattingInfo + << "key:" << mKey + << ")"; + return rDebug.space(); + } + + + + /************************************************************************** + * Implementation: Operators, Helper + **************************************************************************/ + + + #ifndef QT_NO_DEBUG_STREAM + QDebug operator<<(QDebug debug, const PatternFormatter &rPatternFormatter) + { + debug.nospace() << "PatternFormatter(" + << "pattern:" << rPatternFormatter.mPattern << " " + << "converters:("; + int i; + for (i = 0; i < rPatternFormatter.mPatternConverters.size(); i++) + { + if (i > 0) + debug.nospace() << ", "; + debug.nospace() << *rPatternFormatter.mPatternConverters.at(i); + } + debug.nospace() << ") )"; + return debug.space(); + } + #endif + + +#ifndef QT_NO_DEBUG_STREAM + QDebug operator<<(QDebug debug, const FormattingInfo &rFormattingInfo) + { + debug.nospace() << "FormattingInfo(" + << "min:" << FormattingInfo::intToString(rFormattingInfo.mMinLength) << " " + << "max:" << FormattingInfo::intToString(rFormattingInfo.mMaxLength) << " " + << "left:" << rFormattingInfo.mLeftAligned + << ")"; + return debug.space(); + } +#endif // QT_NO_DEBUG_STREAM + + +#ifndef QT_NO_DEBUG_STREAM + QDebug operator<<(QDebug debug, const PatternConverter &rPatternConverter) + { + return rPatternConverter.debug(debug); + } +#endif // QT_NO_DEBUG_STREAM + + + +} // namespace Log4Qt diff --git a/src/log4qt/log4qt/helpers/patternformatter.h b/src/log4qt/log4qt/helpers/patternformatter.h new file mode 100644 index 0000000..fa21a19 --- /dev/null +++ b/src/log4qt/log4qt/helpers/patternformatter.h @@ -0,0 +1,196 @@ +/****************************************************************************** + * + * package: Log4Qt + * file: patternformatter.h + * created: September 2007 + * author: Martin Heinrich + * + * + * Copyright 2007 Martin Heinrich + * + * 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. + * + ******************************************************************************/ + +#ifndef LOG4QT_PATTERNFORMATTER_H +#define LOG4QT_PATTERNFORMATTER_H + +#include "ukui-logmacros.h" + +/****************************************************************************** + * Dependencies + ******************************************************************************/ + +#include +#include + + +/****************************************************************************** + * Declarations + ******************************************************************************/ + + +namespace Log4Qt +{ + + class FormattingInfo; + class PatternConverter; + class LoggingEvent; + + /*! + * \brief The class PatternFormatter formats a logging event based on a + * pattern string. + * + * The class PatternFormatter formats a LoggingEvent base on a pattern + * string. It is used by the patternLayout and TTCCLayout class to + * implement the formatting. + * + * On object construction the provided patterns tring is parsed. Based on + * the information found a chain of PatternConverter is created. Each + * PatternConverter handles a certain member of a LoggingEvent. + * + * \sa PatternLayout::format() + * \sa TTCCLayout::format() + */ + class LIBUKUILOG4QT_EXPORT PatternFormatter + { + public: + /*! + * Creates a PatternFormatter using a the specified \a rPattern. + */ + PatternFormatter(const QString &rPattern); + + /*! + * Destroys the PatternFormatter and all PatternConverter. + */ + virtual ~PatternFormatter(); + + private: + PatternFormatter(const PatternFormatter &rOther); // Not implemented + PatternFormatter &operator=(const PatternFormatter &rOther); // Not implemented + + public: + /*! + * Formats the given \a rLoggingEvent using the chain of + * PatternConverter created during construction from the specified + * pattern. + */ + QString format(const LoggingEvent &rLoggingEvent) const; + + private: + /*! + * If the character \a rDigit is a digit the digit is added to the + * integer \a rValue and the function returns true. Otherwise the + * function returns false. + * + * The function adds the digit by multiplying the existing value + * with ten and adding the numerical value of the digit. If the + * maximum integer value would be exceeded by the operation + * \a rValue is set to INT_MAX. + */ + bool addDigit(const QChar &rDigit, + int &rValue); + + /*! + * Creates a PatternConverter based on the specified conversion + * character \a rChar, the formatting information + * \a rFormattingInfo and the option \a rOption. + * + * The PatternConverter converter is appended to the list of + * PatternConverters. + */ + void createConverter(const QChar &rChar, + const FormattingInfo &rFormattingInfo, + const QString &rOption = QString()); + + /*! + * Creates a LiteralPatternConverter with the string literal + * \a rLiteral. + * + * The PatternConverter converter is appended to the list of + * PatternConverters. + */ + void createLiteralConverter(const QString &rLiteral); + + /*! + * Parses the pattern string specified on construction and creates + * PatternConverter according to it. + */ + void parse(); + + /*! + * Parses an integer option from an option string. If the string is + * not a valid integer or the integer value is less then zero, zero + * is returned. Returns the end of line seperator for the operating + * system. + */ + int parseIntegerOption(const QString &rOption); + + private: + const QString mIgnoreCharacters; + const QString mConversionCharacters; + const QString mOptionCharacters; + QString mPattern; + QList mPatternConverters; + + // Needs to be friend to access internal data + friend QDebug operator<<(QDebug, const PatternFormatter &rPatternFormatter); + }; + + + /************************************************************************** + * Operators, Helper + **************************************************************************/ + +#ifndef QT_NO_DEBUG_STREAM + /*! + * \relates PatternFormatter + * + * Writes all object member variables to the given debug stream \a rDebug and + * returns the stream. + * + * + * %PatternFormatter(pattern:"%r [%t] %p %c %x - %m%n" + * converters:( + * DatePatternConverter(FormattingInfo(min:"0" max:"INT_MAX" left:false) format: "TIME_RELATIVE" ) , + * LiteralPatternConverter(FormattingInfo(min:"0" max:"INT_MAX" left:false) literal: " [" ) , + * BasicPatternConverter(FormattingInfo(min:"0" max:"INT_MAX" left:false) type: "THREAD_CONVERTER" ) , + * LiteralPatternConverter(FormattingInfo(min:"0" max:"INT_MAX" left:false) literal: "] " ) , + * BasicPatternConverter(FormattingInfo(min:"0" max:"INT_MAX" left:false) type: "LEVEL_CONVERTER" ) , + * LiteralPatternConverter(FormattingInfo(min:"0" max:"INT_MAX" left:false) literal: " " ) , + * LoggerPatternConverter(FormattingInfo(min:"0" max:"INT_MAX" left:false) precision: 0 ) , + * LiteralPatternConverter(FormattingInfo(min:"0" max:"INT_MAX" left:false) literal: " " ) , + * BasicPatternConverter(FormattingInfo(min:"0" max:"INT_MAX" left:false) type: "NDC_CONVERTER" ) , + * LiteralPatternConverter(FormattingInfo(min:"0" max:"INT_MAX" left:false) literal: " - " ) , + * BasicPatternConverter(FormattingInfo(min:"0" max:"INT_MAX" left:false) type: "MESSAGE_CONVERTER" ) , + * LiteralPatternConverter(FormattingInfo(min:"0" max:"INT_MAX" left:false) literal: "" ) ) ) + * + * \sa QDebug + */ + QDebug operator<<(QDebug debug, + const PatternFormatter &rPatternFormatter); +#endif // QT_NO_DEBUG_STREAM + + + /************************************************************************** + * Inline + **************************************************************************/ + + +} // namespace Log4Qt + + +Q_DECLARE_TYPEINFO(Log4Qt::PatternFormatter, Q_MOVABLE_TYPE); + + +#endif // LOG4QT_PATTERNFORMATTER_H diff --git a/src/log4qt/log4qt/helpers/properties.cpp b/src/log4qt/log4qt/helpers/properties.cpp new file mode 100644 index 0000000..96d04d7 --- /dev/null +++ b/src/log4qt/log4qt/helpers/properties.cpp @@ -0,0 +1,364 @@ +/****************************************************************************** + * + * package: Log4Qt + * file: properties.cpp + * created: September 2007 + * author: Martin Heinrich + * + * + * Copyright 2007 Martin Heinrich + * + * 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. + * + ******************************************************************************/ + + + +/****************************************************************************** + * Dependencies + ******************************************************************************/ + + +#include "log4qt/helpers/properties.h" + +#include +#include +#include +#include +#include "log4qt/logger.h" + + + +namespace Log4Qt +{ + + + + /************************************************************************** + *Declarations + **************************************************************************/ + + + + /************************************************************************** + * C helper functions + **************************************************************************/ + + + LOG4QT_DECLARE_STATIC_LOGGER(logger, Log4Qt::Properties) + + + + /************************************************************************** + * Class implementation: Properties + **************************************************************************/ + + + void Properties::load(QIODevice *pDevice) + { + const QLatin1Char append_char(msEscapeChar); + + if (!pDevice) + { + logger()->warn("No device specified for load."); + return; + } + + QTextStream stream(pDevice); + QString line; + int line_number = 0; + QString property; + int property_start_line = 1; + + do { + line = trimLeft(stream.readLine()); + line_number++; + + if (!line.isEmpty() && line.at(line.length() - 1) == append_char) + property += line.left(line.length() - 1); + else + { + property += line; + parseProperty(property, property_start_line); + property.clear(); + property_start_line = line_number + 1; + } + } + while (!line.isNull()); + } + + + void Properties::load(const QSettings &rSettings) + { + QStringList keys = rSettings.childKeys(); + QString key; + Q_FOREACH(key, keys) + insert(key, rSettings.value(key).toString()); + } + + + QString Properties::property(const QString &rKey) const + { + // Null string indicates the property does not contain the key. + + if (contains(rKey)) + { + QString value = this->value(rKey); + if (value.isNull()) + return QString(QLatin1String("")); + else + return value; + } + + if (mpDefaultProperties) + return mpDefaultProperties->property(rKey); + else + return QString(); + } + + + QString Properties::property(const QString &rKey, + const QString &rDefaultValue) const + { + QString value = property(rKey); + if (value.isNull()) + return rDefaultValue; + else + return value; + } + + + QStringList Properties::propertyNames() const + { + QStringList default_keys; + if (mpDefaultProperties) + default_keys = mpDefaultProperties->propertyNames(); + + QStringList keys = this->keys(); + QString key; + Q_FOREACH(key, default_keys) + if (!keys.contains(key)) + keys << key; + + return keys; + } + + + void Properties::parseProperty(const QString &rProperty, + int line) + { + Q_ASSERT_X(rProperty == trimLeft(rProperty), "parseProperty()", "rProperty has leading spaces"); + + enum State + { + KEY_STATE, + KEYSPACE_STATE, + SPACEVALUE_STATE, + VALUE_STATE, + KEYESCAPE_STATE, + VALUEESCAPE_STATE, + UNICODEESCAPE_STATE + }; + const QString value_escape_codes =QLatin1String(msValueEscapeCodes); + const QString value_escape_chars = QLatin1String(msValueEscapeChars); + Q_ASSERT_X(value_escape_codes.length() == value_escape_chars.length(), "parseProperty()", "Value escape sequence character definition does not map"); + const QString key_escape_codes = QLatin1String(msKeyEscapeCodes); + const QString key_escape_chars = QLatin1String(msKeyEscapeChars); + Q_ASSERT_X(key_escape_codes.length() == key_escape_chars.length(), "parseProperty()", "Key escape sequence character definition does not map"); + + if (rProperty.isEmpty()) + return; + + int i = 0; + QChar c; + char ch; + State state = KEY_STATE; + QString key; + QString value; + QString *p_string = &key; + uint ucs; + int ucs_digits; + while (i < rProperty.length()) + { + // i points to the current character. + // c contains the current character + // ch contains the Latin1 equivalent of the current character + // i is incremented at the end of the loop to consume the character. + // continue is used to change state without consuming the character + + c = rProperty.at(i); + ch = c.toLatin1(); + + switch (state) + { + case KEY_STATE: + if (ch == '!' || ch == '#' ) + return; + else if (c.isSpace()) + { + p_string = &value; + state = KEYSPACE_STATE; + } + else if (ch == '=' || ch == ':') + { + p_string = &value; + state = SPACEVALUE_STATE; + } + else if (ch == msEscapeChar) + state = KEYESCAPE_STATE; + else + *p_string += c; + break; + case KEYSPACE_STATE: + if (ch == '=' || ch == ':') + state = SPACEVALUE_STATE; + else if (!c.isSpace()) + { + *p_string += c; + state = VALUE_STATE; + } + break; + case SPACEVALUE_STATE: + if (!c.isSpace()) + { + *p_string += c; + state = VALUE_STATE; + } + break; + case VALUE_STATE: + if (ch == msEscapeChar) + state = VALUEESCAPE_STATE; + else + *p_string += c; + break; + case KEYESCAPE_STATE: + { + int convert = key_escape_codes.indexOf(c); + if (convert >= 0) + *p_string += key_escape_chars.at(convert); + else + { + logger()->warn("Unknown escape sequence '\\%1' in key of property starting at line %2", + QString(c), + line); + *p_string += c; + } + state = KEY_STATE; + break; + } + case VALUEESCAPE_STATE: + { + int convert = value_escape_codes.indexOf(c); + if (convert >= 0) + { + *p_string += value_escape_chars.at(convert); + state = VALUE_STATE; + } + else if (ch == 'u') + { + ucs = 0; + ucs_digits = 0; + state = UNICODEESCAPE_STATE; + } + else + { + logger()->warn("Unknown escape sequence '\\%1' in value of property starting at line %2", QString(c), line); + *p_string += c; + state = VALUE_STATE; + } + break; + } + case UNICODEESCAPE_STATE: + { + int hex = hexDigitValue(c); + if (hex >= 0) + { + ucs = ucs * 16 + hex; + ucs_digits++; + if (ucs_digits == 4 || i == rProperty.length() - 1) + { + *p_string += QChar(ucs); + state = VALUE_STATE; + } + } + else + { + if (ucs_digits > 0) + *p_string += QChar(ucs); + state = VALUE_STATE; + continue; + } + break; + } + default: + Q_ASSERT_X(false, "Properties::parseProperty()", "Unknown state constant"); + return; + } + i++; + } + + if (key.isEmpty() && !value.isEmpty()) + logger()->warn("Found value with no key in property starting at line %1", line); + + logger()->trace("Loaded property '%1' : '%2'", key, value); + insert(key, value); + } + + + int Properties::hexDigitValue(const QChar &rDigit) + { + bool ok; + int result = QString(rDigit).toInt(&ok, 16); + if (!ok) + return -1; + else + return result; + } + + + QString Properties::trimLeft(const QString &rLine) + { + int i = 0; + while (i < rLine.length() && rLine.at(i).isSpace()) + i++; + return rLine.right(rLine.length() - i); + } + + + const char Properties::msEscapeChar ='\\'; + const char *Properties::msValueEscapeCodes = "tnr\\\"\' "; + const char *Properties::msValueEscapeChars = "\t\n\r\\\"\' "; + const char *Properties::msKeyEscapeCodes = " :="; + const char *Properties::msKeyEscapeChars = " :="; + + + + /************************************************************************** + * Implementation: Operators, Helper + **************************************************************************/ + + +#ifndef QT_NO_DEBUG_STREAM + QDebug operator<<(QDebug debug, const Properties &rProperties) + { + debug.nospace() << "Properties(" + << "default:" << rProperties.defaultProperties() << " " + << "properties:" << *reinterpret_cast *>(&rProperties) + << ")"; + return debug.space(); + } +#endif + + + +} // namespace Log4Qt diff --git a/src/log4qt/log4qt/helpers/properties.h b/src/log4qt/log4qt/helpers/properties.h new file mode 100644 index 0000000..71566fc --- /dev/null +++ b/src/log4qt/log4qt/helpers/properties.h @@ -0,0 +1,162 @@ +/****************************************************************************** + * + * package: Log4Qt + * file: properties.h + * created: September + * author: Martin Heinrich + * + * + * Copyright 2007 Martin Heinrich + * + * 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. + * + ******************************************************************************/ + +#ifndef LOG4QT_PROPERTIES_H +#define LOG4QT_PROPERTIES_H + +#include "ukui-logmacros.h" + +/****************************************************************************** + * Dependencies + ******************************************************************************/ + +#include +#include + + +/****************************************************************************** + * Declarations + ******************************************************************************/ + +class QIODevice; +class QSettings; + + +namespace Log4Qt +{ + /*! + * \brief The class Properties implements a JAVA property hash. + */ + class LIBUKUILOG4QT_EXPORT Properties : public QHash + { + public: + Properties(Properties *pDefaultProperties = 0); + // virtual ~Properties(); // Use compiler default + // Properties(const Properties &rOther); // Use compiler default + // Properties &operator=(const Properties &rOther); // Not implemented + + public: + Properties *defaultProperties() const; + QString property(const QString &rKey) const; + QString property(const QString &rKey, + const QString &rDefaultValue) const; + void setDefaultProperties(Properties *pDefault); + void setProperty(const QString &rKey, + const QString &rValue); + + // JAVA: void list(QTextStream &rTextStream); + void load(QIODevice *pDevice); + + /*! + * Reads all child keys from the QSettings object \a rSettings and + * inserts them into this object. The value is created using + * QVariant::toString(). Types that do not support toString() are + * resulting in an empty string. + * + * \code + * QSettings settings; + * settings.setValue("Package", "Full"); + * settings.setValue("Background", Qt::white); + * settings.setValue("Support", true); + * settings.setValue("Help/Language", "en_UK"); + * + * Properties properties + * properties.load(&settings) + * + * // properties (("Package", "Full"), ("Background", ""), ("Support", "true")) + * \endcode + */ + void load(const QSettings &rSettings); + + QStringList propertyNames() const; + // JAVA: void save(QIODevice *pDevice) const; + + private: + void parseProperty(const QString &rProperty, + int line); + static int hexDigitValue(const QChar &rDigit); + static QString trimLeft(const QString &rString); + + private: + Properties *mpDefaultProperties; + static const char msEscapeChar; + static const char *msValueEscapeCodes; + static const char *msValueEscapeChars; + static const char *msKeyEscapeCodes; + static const char *msKeyEscapeChars; + }; + + + /************************************************************************** + * Operators, Helper + **************************************************************************/ + +#ifndef QT_NO_DEBUG_STREAM + /*! + * \relates Properties + * + * Writes all object member variables to the given debug stream \a rDebug and + * returns the stream. + * + * + * %Properties(default:0x0 properties:QHash(("log4j.appender.testAppender.layout", "org.apache.log4j.PatternLayout ") + * ("log4j.appender.testAppender.layout.ConversionPattern", "[%t] %-5p %l: %m%n") + * ("log4j.appender.testAppender.Append", "false ") + * ("log4j.appender.testAppender.File", "output/temp ") + * ("log4j.rootCategory", "TRACE, testAppender") + * ("log4j.appender.testAppender", "org.apache.log4j.FileAppender")) ) + * + * \sa QDebug + */ + QDebug operator<<(QDebug debug, + const Properties &rProperties); +#endif // QT_NO_DEBUG_STREAM + + + /************************************************************************** + * Inline + **************************************************************************/ + + inline Properties::Properties(Properties *pDefaultProperties) : + mpDefaultProperties(pDefaultProperties) + {} + + inline Properties *Properties::defaultProperties() const + { return mpDefaultProperties; } + + inline void Properties::setDefaultProperties(Properties *pDefaultProperties) + { mpDefaultProperties = pDefaultProperties; } + + inline void Properties::setProperty(const QString &rKey, + const QString &rValue) + { insert(rKey, rValue); } + + +} // namespace Log4Qt + + +Q_DECLARE_TYPEINFO(Log4Qt::Properties, Q_MOVABLE_TYPE); + + +#endif // LOG4QT_PROPERTIES_H diff --git a/src/log4qt/log4qt/hierarchy.cpp b/src/log4qt/log4qt/hierarchy.cpp new file mode 100644 index 0000000..283c7fd --- /dev/null +++ b/src/log4qt/log4qt/hierarchy.cpp @@ -0,0 +1,212 @@ +/****************************************************************************** + * + * package: Log4Qt + * file: hierarchy.cpp + * created: September 2007 + * author: Martin Heinrich + * + * + * changes: Sep 2008, Martin Heinrich: + * - Fixed problem in Qt 4.4 where QReadWriteLock is by default + * non-recursive. + * + * + * Copyright 2007 - 2008 Martin Heinrich + * + * 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. + * + ******************************************************************************/ + + + +/****************************************************************************** + * Dependencies + ******************************************************************************/ + + +#include "log4qt/hierarchy.h" + +#include +#include "log4qt/logger.h" + + + +namespace Log4Qt +{ + + + /************************************************************************** + * Declarations + **************************************************************************/ + + + + /************************************************************************** + * C helper functions + **************************************************************************/ + + + LOG4QT_DECLARE_STATIC_LOGGER(static_logger, Log4Qt::LoggerRepository) + + + + /************************************************************************** + * Class implementation: Hierarchy + **************************************************************************/ + + + Hierarchy::Hierarchy() : +#if QT_VERSION < QT_VERSION_CHECK(4, 4, 0) + mObjectGuard(), +#else + mObjectGuard(QReadWriteLock::Recursive), +#endif + mLoggers(), + mThreshold(Level::NULL_INT), + mpRootLogger(logger(QString())) + { + // Store root logger to allow rootLogger() to be const + } + + + Hierarchy::~Hierarchy() + { + static_logger()->warn("Unexpected destruction of Hierarchy"); + + // QWriteLocker locker(&mObjectGuard); + // + // resetConfiguration(); + // clear(); + // delete mpRootLogger; + } + + + bool Hierarchy::exists(const QString &rName) const + { + QReadLocker locker(&mObjectGuard); + + return mLoggers.contains(rName); + } + + + Logger *Hierarchy::logger(const QString &rName) + { + QWriteLocker locker(&mObjectGuard); + + return createLogger(rName); + } + + + QList Hierarchy::loggers() const + { + QReadLocker locker(&mObjectGuard); + + return mLoggers.values(); + } + + + void Hierarchy::setThreshold(const QString &rThreshold) + { + setThreshold(Level::fromString(rThreshold)); + } + + + void Hierarchy::resetConfiguration() + { + QWriteLocker locker(&mObjectGuard); + + // Reset all loggers. + // Leave log, qt and root logger to the last to allow debugging of shutdown. + + Logger *p_logging_logger = logger(QLatin1String("Log4Qt")); + Logger *p_qt_logger = logger(QLatin1String("Qt")); + Logger *p_root_logger = rootLogger(); + + Logger *p_logger; + Q_FOREACH(p_logger, mLoggers) + { + if ((p_logger == p_logging_logger) || (p_logger == p_qt_logger) || (p_logger == p_root_logger)) + continue; + resetLogger(p_logger, Level::NULL_INT); + } + resetLogger(p_qt_logger, Level::NULL_INT); + resetLogger(p_logging_logger, Level::NULL_INT); + resetLogger(p_root_logger, Level::DEBUG_INT); + } + + + void Hierarchy::shutdown() + { + static_logger()->debug("Shutting down Hierarchy"); + resetConfiguration(); + } + + +#ifndef QT_NO_DEBUG_STREAM + QDebug Hierarchy::debug(QDebug &rDebug) const + { + rDebug.nospace() << "Hierarchy(" + << "loggers:" << loggers().count() << " " + << "threshold:" << threshold().toString() << " " + << "root-level:" << rootLogger()->level().toString() << " " + << "root-appenders:" << rootLogger()->appenders().count() + << ")"; + return rDebug.space(); + } +#endif // QT_NO_DEBUG_STREAM + + + Logger *Hierarchy::createLogger(const QString &rName) + { + // Q_ASSERT_X(, "Hierarchy::createLogger", "Lock must be held by caller") + + const QString name_separator = QLatin1String("::"); + + Logger *p_logger = mLoggers.value(rName, 0); + if (p_logger != 0) + return p_logger; + + if (rName.isEmpty()) + { + p_logger = new Logger(this, Level::DEBUG_INT, QLatin1String("root"), 0); + mLoggers.insert(QString(), p_logger); + return p_logger; + } + QString parent_name; + int index = rName.lastIndexOf(name_separator); + if (index >=0) + parent_name = rName.left(index); + p_logger = new Logger(this, Level::NULL_INT, rName, createLogger(parent_name)); + mLoggers.insert(rName, p_logger); + return p_logger; + } + + + void Hierarchy::resetLogger(Logger *pLogger, Level level) const + { + // Q_ASSERT_X(, "Hierarchy::resetLogger", "Lock must be held by caller") + + pLogger->removeAllAppenders(); + pLogger->setAdditivity(true); + pLogger->setLevel(level); + } + + + + /************************************************************************** + * Implementation: Operators, Helper + **************************************************************************/ + + + +} // namespace Log4Qt diff --git a/src/log4qt/log4qt/hierarchy.h b/src/log4qt/log4qt/hierarchy.h new file mode 100644 index 0000000..089980c --- /dev/null +++ b/src/log4qt/log4qt/hierarchy.h @@ -0,0 +1,142 @@ +/****************************************************************************** + * + * package: Log4Qt + * file: hierarchy.h + * created: September 2007 + * author: Martin Heinrich + * + * + * Copyright 2007 Martin Heinrich + * + * 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. + * + ******************************************************************************/ + +#ifndef LOG4QT_HIERARCHY_H +#define LOG4QT_HIERARCHY_H + + +/****************************************************************************** + * Dependencies + ******************************************************************************/ + +#include "log4qt/loggerrepository.h" +#include "ukui-logmacros.h" + +#include +#include + + +/****************************************************************************** + * Declarations + ******************************************************************************/ + +namespace Log4Qt +{ + + /*! + * \brief The class Hierarchy implements a logger repository. + * + * \note All the functions declared in this class are thread-safe. + */ + class LIBUKUILOG4QT_EXPORT Hierarchy : public LoggerRepository + { + public: + Hierarchy(); + // Hierarchy(const Hierarchy &rOther); // Use compiler default + virtual ~Hierarchy(); + // Hierarchy &operator=(const Hierarchy &rOther); // Use compiler default + + public: + virtual bool exists(const QString &rName) const; + virtual Logger *logger(const QString &rName); + virtual QList loggers() const; + // JAVA: virtual Logger *logger(const String &rName, LoggerFactory *pFactory); + virtual Logger *rootLogger() const; + virtual Level threshold() const; + virtual void setThreshold(Level level); + virtual void setThreshold(const QString &rThreshold); + + // JAVA: void clear(); + virtual bool isDisabled(Level level); + virtual void resetConfiguration(); + virtual void shutdown(); + + // JAVA: virtual void addHierarchyEventListener(HierarchyEventListener *pEventListener); + // JAVA: virtual void emitNoAppenderWarning(Logger *plogger) const; + // JAVA: virtual void fireAddAppenderEvent(Logger *plogger, Appender *pAppender) const; + + // JAVA: void addRenderer(const QString &rClass, ObjectRenderer *pObjectRenderer); + // JAVA: QHash getRendererMap() const; + // JAVA: setRenderer(const QString &rClass, ObjectRenderer *pObjectRenderer); + + protected: +#ifndef QT_NO_DEBUG_STREAM + /*! + * Writes all object member variables to the given debug stream \a rDebug and + * returns the stream. + * + * + * %Hierarchy(loggers:6 threshold:"ALL" root-level:"DEBUG" root-appenders:0) + * + * \sa QDebug, operator<<(QDebug debug, const LoggerRepository &rLoggerRepository) + */ + virtual QDebug debug(QDebug &rdebug) const; +#endif + + private: + Logger *createLogger(const QString &rName); + void resetLogger(Logger *pLogger, Level level) const; + + private: + mutable QReadWriteLock mObjectGuard; + QHash mLoggers; + volatile bool mHandleQtMessages; + Level mThreshold; + Logger *mpRootLogger; + }; + + + /************************************************************************** + * Operators, Helper + **************************************************************************/ + + + /************************************************************************** + * Inline + **************************************************************************/ + + inline Logger *Hierarchy::rootLogger() const + { // QReadLocker locker(&mObjectGuard); // Constant for object lifetime + return mpRootLogger; } + + inline Level Hierarchy::threshold() const + { // QReadLocker locker(&mObjectGuard); // Level is threadsafe + return mThreshold; } + + inline void Hierarchy::setThreshold(Level level) + { // QReadLocker locker(&mObjectGuard); // Level is threadsafe + mThreshold = level; } + + inline bool Hierarchy::isDisabled(Level level) + { // QReadLocker locker(&mObjectGuard); // Level is threadsafe + return level < mThreshold; } + + +} // namespace Log4Qt + + +// Q_DECLARE_TYPEINFO(Log4Qt::Hierarchy, Q_COMPLEX_TYPE); // Use default + + +#endif // LOG4QT_HIERARCHY_H diff --git a/src/log4qt/log4qt/layout.cpp b/src/log4qt/log4qt/layout.cpp new file mode 100644 index 0000000..160f80d --- /dev/null +++ b/src/log4qt/log4qt/layout.cpp @@ -0,0 +1,91 @@ +/****************************************************************************** + * + * package: Log4Qt + * file: layout.cpp + * created: September 2007 + * author: Martin Heinrich + * + * + * Copyright 2007 Martin Heinrich + * + * 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. + * + ******************************************************************************/ + + + +/****************************************************************************** + * Dependencies + ******************************************************************************/ + + +#include "log4qt/layout.h" + +#include +#include "log4qt/loggingevent.h" +#include "log4qt/logmanager.h" + + + +namespace Log4Qt +{ + + + /*************************************************************************** + * Declarations + **************************************************************************/ + + + + /************************************************************************** + * C helper functions + **************************************************************************/ + + + + /************************************************************************** + * Class implementation: Layout + **************************************************************************/ + + + QString Layout::contentType() const + { + return QString::fromLatin1("text/plain"); + } + + + void Layout::activateOptions() + { + } + + + QString Layout::endOfLine() + { + // There seams to be no function in Qt for this + +#ifdef Q_OS_WIN32 + return QLatin1String("\r\n"); +#endif // Q_OS_WIN32 +//#ifdef Q_OS_MAC +// return QLatin1String("\r"); +//#endif // Q_OS_MAC + return QLatin1String("\n"); + } + + + /************************************************************************** + * Implementation: Operators, Helper + **************************************************************************/ + + +} // namespace Log4Qt diff --git a/src/log4qt/log4qt/layout.h b/src/log4qt/log4qt/layout.h new file mode 100644 index 0000000..117cbef --- /dev/null +++ b/src/log4qt/log4qt/layout.h @@ -0,0 +1,157 @@ +/****************************************************************************** + * + * package: Log4Qt + * file: layout.h + * created: September 2007 + * author: Martin Heinrich + * + * + * Copyright 2007 Martin Heinrich + * + * 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. + * + ******************************************************************************/ + +#ifndef LOG4QT_LAYOUT_H +#define LOG4QT_LAYOUT_H + + +/****************************************************************************** + * Dependencies + ******************************************************************************/ + +#include "log4qt/helpers/logobject.h" + +#include "log4qt/helpers/logobjectptr.h" +#include "log4qt/log4qt.h" +#include "ukui-logmacros.h" + + +/****************************************************************************** + * Declarations + ******************************************************************************/ + +namespace Log4Qt +{ + + class LoggingEvent; + + /*! + * \brief The class Layout is the base class for all layouts. + * + * \note The ownership and lifetime of objects of this class are managed. See + * \ref Ownership "Object ownership" for more details. + */ + class LIBUKUILOG4QT_EXPORT Layout : public LogObject + { + Q_OBJECT + + /*! + * The property holds the content type of the layout. + * + * \sa contentType() + */ + Q_PROPERTY(QString footercontentType READ contentType) + /*! + * The property holds the footer used by the layout. + * + * \sa footer(), setFooter() + */ + Q_PROPERTY(QString footer READ footer WRITE setFooter) + /*! + * The property holds the header used by the layout. + * + * \sa header(), setHeader() + */ + Q_PROPERTY(QString header READ header WRITE setHeader) + + public: + Layout(QObject *pParent = 0); + virtual ~Layout(); + private: + Layout(const Layout &rOther); // Not implemented + Layout &operator=(const Layout &rOther); // Not implemented + + public: + virtual QString contentType() const; + QString footer() const; + QString header() const; + // JAVA: virtual bool ignoresThrowable() const; + QString name() const; + void setFooter(const QString &rFooter); + void setHeader(const QString &rHeader); + void setName(const QString &rName); + // JAVA: void setIgnoresThrowable(bool) const; + + virtual void activateOptions(); + virtual QString format(const LoggingEvent &rEvent) = 0; + + /*! + * Returns the end of line seperator for the operating system. + * + * Windows: \\r\\n + * Mac: \\r + * UNIX: \\n + */ + static QString endOfLine(); + + // Member variables + private: + QString mFooter; + QString mHeader; + }; + + + /************************************************************************** + * Operators, Helper + **************************************************************************/ + + + /************************************************************************** + * Inline + **************************************************************************/ + + inline Layout::Layout(QObject *pParent) : + LogObject(pParent) + {} + + inline Layout::~Layout() + {} + + inline QString Layout::footer() const + { return mFooter; } + + inline QString Layout::header() const + { return mHeader; } + + inline QString Layout::name() const + { return objectName(); } + + inline void Layout::setFooter(const QString &rFooter) + { mFooter = rFooter; } + + inline void Layout::setHeader(const QString &rHeader) + { mHeader = rHeader; } + + inline void Layout::setName(const QString &rName) + { setObjectName(rName); } + + +} // namespace Log4Qt + + +// Q_DECLARE_TYPEINFO(Log4Qt::Layout, Q_COMPLEX_TYPE); // Use default +Q_DECLARE_TYPEINFO(Log4Qt::LogObjectPtr, Q_MOVABLE_TYPE); + + +#endif // LOG4QT_LAYOUT_H diff --git a/src/log4qt/log4qt/level.cpp b/src/log4qt/log4qt/level.cpp new file mode 100644 index 0000000..a55038f --- /dev/null +++ b/src/log4qt/log4qt/level.cpp @@ -0,0 +1,204 @@ +/****************************************************************************** + * + * package: Log4Qt + * file: level.cpp + * created: September 2007 + * author: Martin Heinrich + * + * + * Copyright 2007 Martin Heinrich + * + * 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. + * + ******************************************************************************/ + + + +/****************************************************************************** + * Dependencies + ******************************************************************************/ + + +#include "log4qt/level.h" + +#include +#include +#include +#include "log4qt/logger.h" + + +namespace Log4Qt +{ + + + /************************************************************************** + * Declarations + **************************************************************************/ + + + + /************************************************************************** + * C helper functions + **************************************************************************/ + + + LOG4QT_DECLARE_STATIC_LOGGER(logger, Log4Qt::Level) + + + + /************************************************************************** + * Class implementation: Level + **************************************************************************/ + + + int Level::syslogEquivalent() const + { + // QMutexLocker locker(&mObjectGuard); // Read/Write of int is safe + + switch (mValue) + { + case NULL_INT: + case ALL_INT: + case TRACE_INT: + case DEBUG_INT: + return 7; + case INFO_INT: + return 6; + case WARN_INT: + return 4; + case ERROR_INT: + return 3; + case FATAL_INT: + case OFF_INT: + return 0; + default: + Q_ASSERT_X(false, "Level::syslogEquivalent()", "Unknown level value"); + return 7; + } + } + + + QString Level::toString() const + { + // QMutexLocker locker(&mObjectGuard); // Read/Write of int is safe + + const char *p_context = "Level"; + + switch (mValue) + { + case NULL_INT: + return QCoreApplication::translate(p_context, "NULL"); + case ALL_INT: + return QCoreApplication::translate(p_context, "ALL"); + case TRACE_INT: + return QCoreApplication::translate(p_context, "TRACE"); + case DEBUG_INT: + return QCoreApplication::translate(p_context, "DEBUG"); + case INFO_INT: + return QCoreApplication::translate(p_context, "INFO"); + case WARN_INT: + return QCoreApplication::translate(p_context, "WARN"); + case ERROR_INT: + return QCoreApplication::translate(p_context, "ERROR"); + case FATAL_INT: + return QCoreApplication::translate(p_context, "FATAL"); + case OFF_INT: + return QCoreApplication::translate(p_context, "OFF"); + default: + Q_ASSERT_X(false, "Level::toString()", "Unknown level value"); + return QCoreApplication::translate(p_context, "NULL"); + } + } + + + Level Level::fromString(const QString &rLevel, bool *pOk) + { + const char *p_context = "Level"; + if (pOk) + *pOk = true; + + if (rLevel == QLatin1String("OFF") || + rLevel == QCoreApplication::translate(p_context, "OFF")) + return OFF_INT; + if (rLevel == QLatin1String("FATAL") || + rLevel == QCoreApplication::translate(p_context, "FATAL")) + return FATAL_INT; + if (rLevel == QLatin1String("ERROR") || + rLevel == QCoreApplication::translate(p_context, "ERROR")) + return ERROR_INT; + if (rLevel == QLatin1String("WARN") || + rLevel == QCoreApplication::translate(p_context, "WARN")) + return WARN_INT; + if (rLevel == QLatin1String("INFO") || + rLevel == QCoreApplication::translate(p_context, "INFO")) + return INFO_INT; + if (rLevel == QLatin1String("DEBUG") || + rLevel == QCoreApplication::translate(p_context, "DEBUG")) + return DEBUG_INT; + if (rLevel == QLatin1String("TRACE") || + rLevel == QCoreApplication::translate(p_context, "TRACE")) + return TRACE_INT; + if (rLevel == QLatin1String("ALL") || + rLevel == QCoreApplication::translate(p_context, "ALL")) + return ALL_INT; + if (rLevel == QLatin1String("NULL") || + rLevel == QCoreApplication::translate(p_context, "NULL")) + return NULL_INT; + + logger()->warn("Use of invalid level string '%1'. Using 'Level::NULL_INT' instead.", rLevel); + if (pOk) + *pOk = false; + return NULL_INT; + } + + + + /************************************************************************** + * Implementation: Operators, Helper + **************************************************************************/ + + +#ifndef QT_NO_DATASTREAM + QDataStream &operator<<(QDataStream &rStream, + const Level &rLevel) + { + quint8 l = rLevel.mValue; + rStream << l; + return rStream; + } + + + QDataStream &operator>>(QDataStream &rStream, + Level &rLevel) + { + quint8 l; + rStream >> l; + rLevel.mValue = (Level::Value)l; + return rStream; + } +#endif // QT_NO_DATASTREAM + + +#ifndef QT_NO_DEBUG_STREAM + QDebug operator<<(QDebug debug, + const Level &rLevel) + { + debug.nospace() << "Level(" + << rLevel.toString() + << ")"; + return debug.space(); + } +#endif // QT_NO_DEBUG_STREAM + + +} // namespace Log4Qt diff --git a/src/log4qt/log4qt/level.h b/src/log4qt/log4qt/level.h new file mode 100644 index 0000000..6fd26f1 --- /dev/null +++ b/src/log4qt/log4qt/level.h @@ -0,0 +1,194 @@ +/****************************************************************************** + * + * package: Log4Qt + * file: level.h + * created: September 2007 + * author: Martin Heinrich + * + * + * Copyright 2007 Martin Heinrich + * + * 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. + * + ******************************************************************************/ + +#ifndef LOG4QT_LEVEL_H +#define LOG4QT_LEVEL_H + + +/****************************************************************************** + * Dependencies + ******************************************************************************/ + +#include +#include +#include "log4qt/log4qt.h" +#include "ukui-logmacros.h" + + +/****************************************************************************** + * Declarations + ******************************************************************************/ + +namespace Log4Qt +{ + + /*! + * \brief The class Level defines the level of a logging event. + * + * \note All the functions declared in this class are thread-safe. + */ + class LIBUKUILOG4QT_EXPORT Level + { + public: + // Comparisson operators rely on the order: + // NULL_INT < ALL_INT < TRACE_INT < ... + // Serialisation uses unsigned 8 bit int + + /*! + * The enumeration Value contains all possible Level values. + */ + enum Value + { + /*! NULL_INT is used for no level has been specified */ + NULL_INT = 0, + ALL_INT = 32, + TRACE_INT = 64, + DEBUG_INT = 96, + INFO_INT = 128, + WARN_INT = 150, + ERROR_INT = 182, + FATAL_INT = 214, + OFF_INT = 255 + }; + + public: + Level(Value value = NULL_INT); + // Level(const Level &rOther); // Use compiler default + // virtual ~Level(); // Use compiler default + // Level &operator=(const Level &rOther); // Use compiler default + + int syslogEquivalent() const; + int toInt() const; + + bool operator==(const Level &rOther) const; + bool operator!=(const Level &rOther) const; + bool operator<(const Level &rOther) const; + bool operator<=(const Level &rOther) const; + bool operator>(const Level &rOther) const; + bool operator>=(const Level &rOther) const; + QString toString() const; + + static Level fromString(const QString &rName, bool *pOk = 0); + + private: + // QMutex mObjectGuard; + volatile Value mValue; + +#ifndef QT_NO_DATASTREAM + // Needs to be friend to stream objects + friend QDataStream &operator<<(QDataStream &rStream, + const Level &rLevel); + friend QDataStream &operator>>(QDataStream &rStream, + Level &rLevel); +#endif // QT_NO_DATASTREAM + }; + + + /************************************************************************** + * Operators, Helper + **************************************************************************/ + +#ifndef QT_NO_DATASTREAM + /*! + * \relates Level + * + * Writes the given error \a rLevel to the given stream \a rStream, + * and returns a reference to the stream. + */ + QDataStream &operator<<(QDataStream &rStream, + const Level &rLevel); + + /*! + * \relates Level + * + * Reads an error from the given stream \a rStream into the given + * error \a rLevel, and returns a reference to the stream. + */ + QDataStream &operator>>(QDataStream &rStream, + Level &rLevel); +#endif // QT_NO_DATASTREAM + +#ifndef QT_NO_DEBUG_STREAM + /*! + * \relates Level + * + * Writes all object member variables to the given debug stream \a rDebug + * and returns the stream. + * + * + * %Level("ERROR") + * + * \sa QDebug + */ + QDebug operator<<(QDebug debug, + const Level &rLevel); +#endif // QT_NO_DEBUG_STREAM + + + /************************************************************************** + * Inline + **************************************************************************/ + + + inline Level::Level(Value value) : + mValue(value) + {} + + inline int Level::toInt() const + { // QMutexLocker locker(&mObjectGuard); // Read/Write of int is safe + return mValue; } + + inline bool Level::operator==(const Level &rOther) const + { // QMutexLocker locker(&mObjectGuard); // Read/Write of int is safe + return mValue == rOther.mValue; } + + inline bool Level::operator!=(const Level &rOther) const + { // QMutexLocker locker(&mObjectGuard); // Read/Write of int is safe + return mValue != rOther.mValue; } + + inline bool Level::operator<(const Level &rOther) const + { // QMutexLocker locker(&mObjectGuard); // Read/Write of int is safe + return mValue < rOther.mValue; } + + inline bool Level::operator<=(const Level &rOther) const + { // QMutexLocker locker(&mObjectGuard); // Read/Write of int is safe + return mValue <= rOther.mValue; } + + inline bool Level::operator>(const Level &rOther) const + { // QMutexLocker locker(&mObjectGuard); // Read/Write of int is safe + return mValue > rOther.mValue; } + + inline bool Level::operator>=(const Level &rOther) const + { // QMutexLocker locker(&mObjectGuard); // Read/Write of int is safe + return mValue >= rOther.mValue; } + + +} // namespace Log4Qt + + +Q_DECLARE_METATYPE(Log4Qt::Level) +Q_DECLARE_TYPEINFO(Log4Qt::Level, Q_MOVABLE_TYPE); + + +#endif // LOG4QT_LEVEL_H diff --git a/src/log4qt/log4qt/log4qt.cpp b/src/log4qt/log4qt/log4qt.cpp new file mode 100644 index 0000000..9378f46 --- /dev/null +++ b/src/log4qt/log4qt/log4qt.cpp @@ -0,0 +1,58 @@ +/****************************************************************************** + * + * package: Log4Qt + * file: logging.cpp + * created: September 2007 + * author: Martin Heinrich + * + * + * Copyright 2007 Martin Heinrich + * + * 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. + * + *****************************************************************************/ + + + +/****************************************************************************** + *Dependencies + ******************************************************************************/ + + +#include "log4qt/log4qt.h" + + + +namespace Log4Qt +{ + + + /************************************************************************** + * Declarations + **************************************************************************/ + + + + /************************************************************************** + * C helper functions + **************************************************************************/ + + + + /************************************************************************** + *Implementation: Operators, Helper + **************************************************************************/ + + + +} // namespace Log4Qt diff --git a/src/log4qt/log4qt/log4qt.h b/src/log4qt/log4qt/log4qt.h new file mode 100644 index 0000000..641f196 --- /dev/null +++ b/src/log4qt/log4qt/log4qt.h @@ -0,0 +1,616 @@ +/****************************************************************************** + * + * package: Log4Qt + * file: logging.h + * created: September 2007 + * author: Martin Heinrich + * + * + * changes: Sep 2008, Martin Heinrich: + * - Added a compile time version check for the Qt version + * Jan 2009, Martin Heinrich: + * - Updated documentation and version information for version 0.2 + * Feb 2009, Martin Heinrich: + * - Updated version information for version 0.3 + * + * + * Copyright 2007 - 2009 Martin Heinrich + * + * 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. + * + ******************************************************************************/ + +#ifndef LOG4QT_H +#define LOG4QT_H + + +/*! + * \mainpage + * + * %Log4Qt is a C++ port of the Apache Software Foundation Log4j package + * using the Trolltech Qt Framework. + * + * The documentation describes classes and methods that have been added or + * changed compared to Log4j. + * + * The following sections are describing the implementation in more detail: + * - \ref Changes "Differences to Log4j" + * - \ref Ownership "Object ownership" + * - \ref LogLog "Logging within the package" + * - \ref Init "Initialization procedure" + * - \ref Env "Environment Variables" + * - \ref Undocumented "Undocumented functions" + * - \ref Assumptions "Assumptions" + * + * \author Martin Heinrich + * \version 0.3 (January 2009) + * + */ + +/*! + * \page Changes Differences to Log4j + * + * The following fundamental differences exist between %Log4Qt and Log4j: + * + * - As a JAVA package Log4j does not have to manage object ownership and + * lifetime in the same way then it is required in C++. For details on + * how object ownership is handled see \ref Ownership "Object ownership". + * - The package uses itself for its internal logging similar to Log4j 1.3. + * For details see \ref LogLog "Logging within the package". + * - The configuration using system properties was replaced with a combination + * of environment variables and application settings. For details see + * \ref Env "Environment Variables". + * - Custom levels are not supported. + * - Multiple Logger Repositories are not supported + * + * The following classes have been changed: + * + * - \ref Log4Qt::AppenderSkeleton "AppenderSkeleton" + * - The procedure of checking, if logging is possible, originally used by + * \ref Log4Qt::WriterAppender "WriterAppender" was generalised and is used + * in \ref Log4Qt::AppenderSkeleton "AppenderSkeleton" and derived classes + * (\ref Log4Qt::AppenderSkeleton::checkEntryConditions() "checkEntryConditions()"). + * - The \ref Log4Qt::AppenderSkeleton::doAppend() "doAppend()" member function will + * check the entry conditions by calling the sub-class specific + * \ref Log4Qt::AppenderSkeleton::checkEntryConditions() "checkEntryConditions()". + * If successful the sub-class specific + * \ref Log4Qt::AppenderSkeleton::append() "append()" function is called. + * + * - Configurator + * - Configure functions return a boolean indicating, if the configuration + * was successful. + * - Configure errors are accessible over + * \ref Log4Qt::ConfiguratorHelper::configureError() + * "ConfiguratorHelper::configureError()". + * - Watching for configuration file changes is a function performed + * centrally by the \ref Log4Qt::ConfiguratorHelper "ConfiguratorHelper". + * The class provides signals to notify on configuration change and errors. + * - The class \ref Log4Qt::PropertyConfigurator "PropertyConfigurator" was + * extended to be able to read configuration data from a QSettings object. + * + * - \ref Log4Qt::Level "Level" + * - A new value \ref Log4Qt::Level::NULL_INT "Level::NULL_INT" was + * introduced to indicate there is no level set. + * + * - \ref Log4Qt::Logger "Logger" + * - The method \ref Log4Qt::Logger::isEnabledFor() "isEnabledFor()" + * does also take the repository threshold into account. + * - Several overloaded convenience member function are available to log + * messages with arguments of different types. + * - Two macros, \ref Log4Qt::LOG4QT_DECLARE_STATIC_LOGGER "LOG4QT_DECLARE_STATIC_LOGGER" + * and \ref Log4Qt::LOG4QT_DECLARE_QCLASS_LOGGER "LOG4QT_DECLARE_QCLASS_LOGGER", + * allows retrieving and caching of a pointer to a logger object. + * + * - \ref Log4Qt::LogManager "LogManager" + * - A QtMessage handler can be installed via + * \ref Log4Qt::LogManager::setHandleQtMessages() "setHandleQtMessages()", + * to redirect all messages created by calls to qDebug(), qWarning(), + * qCritical() and qFatal() to a logger. The logger is named Qt and can be + * accessed using \ref Log4Qt::LogManager::qtLogger() "qtLogger()". + * - The initialisation procedure is available over a public method + * (\ref Log4Qt::LogManager::startup() "startup()"). + * - The LogManager provides access to the logger used internally by the + * package (\ref Log4Qt::LogManager::logLogger() "logLogger()") and to + * its default initialisation procedure + * (\ref Log4Qt::LogManager::configureLogLogger() "configureLogLogger()"). + * + * - \ref Log4Qt::WriterAppender "WriterAppender" + * - The class will call \ref Log4Qt::WriterAppender::handleIoErrors() + * "handleIoErrors()" after all I/O operations. Sub-classes should + * re-implement the function to handle errors. + * + * The following classes have been added: + * + * - An additional appender class, \ref Log4Qt::DebugAppender "DebugAppender", + * was added. The class appends logging events to the platform specific debug + * output. + * - Various helper class have been introduced: + * - \ref Log4Qt::ClassLogger "ClassLogger": The class ClassLogger provides + * logging for a QObject derived class. + * - \ref Log4Qt::ConfiguratorHelper "ConfiguratorHelper": The class + * ConfiguratorHelper provides a configuration file watch and last error + * for configurator classes. + * - \ref Log4Qt::DateTime "DateTime": The class DateTime provides extended + * functionality for QDateTime. + * - \ref Log4Qt::LogError "LogError": The class LogError represents an error. + * - \ref Log4Qt::Factory "Factory": The class Factory provides factories + * for Appender, Filter and Layout objects. + * - \ref Log4Qt::InitialisationHelper "InitialisationHelper": The class + * InitialisationHelper performs static initialisation tasks. + * - \ref Log4Qt::LogObject "LogObject": The class LogObject is the common + * base class for many classes in the package. + * - \ref Log4Qt::LogObjectPtr "LogObjectPtr": The class LogObjectPtr + * implements automatic reference counting for LogObject objects. + * - \ref Log4Qt::PatternFormatter "PatternFormatter": The class + * PatternFormatter formats a logging event based on a pattern string. + * - \ref Log4Qt::Properties "Properties": The class Properties implements a + * JAVA property hash. + */ + +/*! + * \page Ownership Object ownership + * + * In difference to the JAVA Log4j package %Log4Qt must manage ownership and + * lifetime of the objects used. This is non trivial as objects are created + * and used in different ways. + * + * In general an object can be created explicitly for example an application + * may create Loggers, Appenders and Layouts during creation of a QApplication + * object. But they can also be automatically created by the package on + * startup using a \ref Log4Qt::PropertyConfigurator "PropertyConfigurator" + * configuration file. Objects may also be created the one way and then used + * the other. Object may be used by multiple other objects. A Layout for example + * may be used by multiple Appenders. Objects are also created from multiple + * threads. The creation may happen during static initialisation and the + * deletion during static de-initialization. + * + * The parent child model used by QObject cannot be used to handle this. It + * cannot automatically delete an object that is used by multiple others as + * for example an Appender used by multiple Loggers. In addition to this + * QObjects and their children must reside in the same thread. This would + * either mean to impose restriction on how objects can be created or to move + * objects to a specific thread. + * + * To allow an automatic deletion of not required objects the package + * implements reference counting for Appenders, Layouts and Filters. The + * reference counting is implemented in \ref Log4Qt::LogObject "LogObject", + * which is used as a common base class. The reference count can be explicitly + * changed using the methods \ref Log4Qt::LogObject::retain() "retain()" and + * \ref Log4Qt::LogObject::release() "release()". Alternatively an auto pointer + * is available \ref Log4Qt::LogObjectPtr "LogObjectPtr", which is used + * throughout the package. + * + * The reference counting mechanism will test, if an object has a QObject + * parent object set. If a parent is set, the object will not be deleted, if + * the reference count reaches 0. This allows to mix the reference counted + * paradigm with the QObject parent child one. + * + * The following example configures a logger and uses reference counting to + * manage the ownership of objects. + * + * \code + * // Create layout + * TTCCLayout *p_layout = new TTCCLayout(); + * + * // Create appender + * ConsoleAppender *p_appender = new ConsoleAppender(p_layout, ConsoleAppender::STDOUT_TARGET); + * p_appender->activateOptions(); + * + * // Get logger + * Logger *p_logger = Logger::logger("MyClass"); + * p_logger->addAppender(p_appender); + * + * // ... + * + * // Remove appender from Logger + * p_logger->removeAllAppenders(); // p_appender and p_layout are deleted here + * \endcode + * + * The following example configures a logger and uses QObject ownership of + * objects. + * + * \code + * QObject *p_parent = new MyObject; + * + * // Create objects + * ConsoleAppender *p_appender = new ConsoleAppender(p_parent); + * TTCCLayout *p_layout = new TTCCLayout(p_appender); + * + * // Configure appender + * p_appender->setTarget(ConsoleAppender::STDOUT_TARGET); + * p_appender->setLayout(p_layout); + * p_appender->activateOptions(); + * + * // Get logger + * Logger *p_logger = Logger::logger("MyClass"); + * p_logger->addAppender(p_appender); + * + * // ... + * + * // Remove appender from Logger + * p_logger->removeAllAppenders(); + * + * delete p_parent; // p_appender and p_layout are deleted here + * \endcode + * + * The following example shows how to use objects created on the stack. + * + * \code + * { + * // Create layout + * TTCCLayout layout; + * layout.retain(); + * + * // Create appender + * ConsoleAppender appender(&layout, ConsoleAppender::STDOUT_TARGET); + * appender.retain(); + * appender.activateOptions(); + * + * // Get logger + * Logger *p_logger = Logger::logger("MyClass"); + * p_logger->addAppender(&appender); + * + * // ... + * + * // Remove appender from Logger + * p_logger->removeAllAppenders(); // Without retain() program crashes here + * + * } // p_appender and p_layout are deleted here + * \endcode + */ + +/*! + * \page LogLog Logging within the package + * + * The package uses itself for logging similar to Log4j 1.3. This brings much + * more flexibility over logging to stdout, stderr like in Log4j 1.2 using + * logLog. It also enables the program to capture and handle errors raised by + * the package. + * + * Using this approach introduces the issue of recursion. The following example + * explains a situation where this happens. Let's say all logger are configured + * to be additive and only the root logger has an appender set. The appender + * is a \ref Log4Qt::FileAppender "FileAppender". During the logging of an + * event an I/O error occurs. The \ref Log4Qt::FileAppender "FileAppender" logs + * an event by itself using the logger %Log4Qt::FileAppender. The event is + * passed to the root logger, which calls then the \ref Log4Qt::FileAppender + * "FileAppender". This causes another I/O error, which is logged by + * the \ref Log4Qt::FileAppender "FileAppender". + * + * To avoid an endless loop the appender will drop the event on a recursive + * invocation. This check is done by \ref Log4Qt::AppenderSkeleton + * "AppenderSkeleton" in \ref Log4Qt::AppenderSkeleton::doAppend() + * "doAppend()". + * + * The problem only occurs, if a logger, appender, layout or filter log an + * event while an event is appended. Neither the logger class nor any of the + * layout or filter classes log events during appending of an event. Most of + * the appender classes may log errors during appending. Only the + * \ref Log4Qt::ListAppender "ListAppender" and + * \ref Log4Qt::ListAppender "ConsoleAppender" are not logging events. + * + * The default configuration uses two \ref Log4Qt::ListAppender + * "ConsoleAppender", one for stderr and one for stdout. No event will be + * dropped, because no recursive invocations can occur. + */ + +/*! + * \page Init Initialization procedure + * + * The package is initialised in two stages. The first stage takes place during + * static initialization. The second stage takes place when the + * \ref Log4Qt::LogManager "LogManager" singleton is created. + * + * During static initialisation the \ref Log4Qt::InitialisationHelper + * "InitialisationHelper" singleton is created . On construction it captures + * the program startup time, reads the required values from the system + * environment and registers the package types with the Qt type system. + * + * The \ref Log4Qt::LogManager "LogManager" singleton is created on first use. + * The creation is usually triggered by the request for a \ref Log4Qt::Logger + * "Logger" object. The call to \ref Log4Qt::Logger::logger() + * "Logger::logger()" is passed through to \ref Log4Qt::LogManager::logger() + * "LogManager::logger()". On creation the \ref Log4Qt::LogManager "LogManager" + * creates a \ref Log4Qt::Hierarchy "Hierarchy" object as logger repository. + * + * After the singleton is created the logging of the package is configured to + * its default by a call to \ref Log4Qt::LogManager::configureLogLogger() + * "LogManager::configureLogLogger()". The logger + * \ref Log4Qt::LogManager::logLogger() "logLogger()" is configured to be not + * additive. Messages with the level \ref Log4Qt::Level::ERROR_INT + * "Level::ERROR_INT" and \ref Log4Qt::Level::FATAL_INT "Level::FATAL_INT" are + * written to \c stderr using a ConsoleAppender. The remaining messages are + * written to \c stdout using a second ConsoleAppender. The level is read from + * the system environment or application settings using + * \ref Log4Qt::InitialisationHelper::setting() + * "InitialisationHelper::setting()" with the key \c Debug. If a level value + * is found, but it is not a valid Level string, + * \ref Log4Qt::Level::DEBUG_INT "Level::DEBUG_INT" is used. If no level string + * is found \ref Log4Qt::Level::ERROR_INT "Level::ERROR_INT" is used. + * + * Once the logging is configured the package is initialised by a call to + * \ref Log4Qt::LogManager::startup() "LogManager::startup()". The function + * will test for the setting \c DefaultInitOverride in the system environment + * and application settings using \ref Log4Qt::InitialisationHelper::setting() + * "InitialisationHelper::setting()". If the value is present and set to + * anything else then \c false, the initialisation is aborted.
+ * The system environment and application settings are tested for the setting + * \c Configuration. If it is found and it is a valid path to a file, the + * package is configured with the file using + * \ref Log4Qt::PropertyConfigurator::doConfigure(const QString &, LoggerRepository *) + * "PropertyConfigurator::doConfigure()". If the setting \c Configuration is + * not available and a QCoreApplication object is present, the application + * settings are tested for a group \c Log4Qt/Properties. If the group exists, + * the package is configured with the setting using the + * \ref Log4Qt::PropertyConfigurator::doConfigure(const QSettings &r, LoggerRepository *) + * "PropertyConfiguratordoConfigure()". If neither a configuration file nor + * configuration settings could be found, the current working directory is + * searched for the file \c "log4qt.properties". If it is found, the package + * is configured with the file using + * \ref Log4Qt::PropertyConfigurator::doConfigure(const QString &, LoggerRepository *) + * "PropertyConfigurator::doConfigure()". + * + * The following example shows how to use application settings to initialise the + * package. + * + * \code + * # file: myapplication.h + * + * #include qapplication.h + * + * class MyApplication : public QApplication + * { + * Q_OBJECT + * + * public: + * MyApplication(); + * ~MyApplication(); + * void setupLog4Qt(); + * } + * \endcode + * \code + * # file: myapplication.cpp + * + * #include myapplication.h + * + * MyApplication::MyApplication( + * { + * // Set Application data to allow Log4Qt initialisation to read the + * // correct values + * setApplicationName("MyApplication"); + * setOrganisationName("MyOrganisation"); + * setOrganizationDomain("www.myorganisation.com"); + * + * // Log first message, which initialises Log4Qt + * Log4Qt::Logger::logger("MyApplication")->info("Hello World"); + * } + * + * MyApplication::~MyApplication() + * { + * } + * + * void MyApplication::setupLog4Qt() + * { + * QSettings s; + * + * // Set logging level for Log4Qt to TRACE + * s.beginGroup("Log4Qt"); + * s.setValue("Debug", "TRACE"); + * + * // Configure logging to log to the file C:/myapp.log using the level TRACE + * s.beginGroup("Properties"); + * s.setValue("log4j.appender.A1", "org.apache.log4j.FileAppender"); + * s.setValue("log4j.appender.A1.file", "C:/myapp.log"); + * s.setValue("log4j.appender.A1.layout", "org.apache.log4j.TTCCLayout"); + * s.setValue("log4j.appender.A1.layout.DateFormat", "ISO8601"); + * s.setValue("log4j.rootLogger", "TRACE, A1"); + * + * // Settings will become active on next application startup + * } + * \endcode + */ + +/*! + * \page Env Environment Variables + * + * The package uses environment variables to control the initialization + * procedure. The environment variables replace the system property entries + * used by Log4j. + * + * For compability reasons the Log4j entry is recognised. Alternatively a + * environment variable style Log4Qt form can be used. The following entries + * are used: + * + * - LOG4QT_DEBUG
+ * The variable controls the \ref Log4Qt::Level "Level" value for the + * logger \ref Log4Qt::LogManager::logLogger() "LogManager::logLogger()". + * If the value is a valid \ref Log4Qt::Level "Level" string, the level for + * the is set to the level. If the value is not a valid + * \ref Log4Qt::Level "Level" string, \ref Log4Qt::Level::DEBUG_INT + * "DEBUG_INT" is used. Otherwise \ref Log4Qt::Level::ERROR_INT "ERROR_INT" + * is used. + * - \ref Log4Qt::LogManager::configureLogLogger() + * "LogManager::configureLogLogger()" + * + * - LOG4QT_DEFAULTINITOVERRIDE
+ * The variable controls the \ref Init "initialization procedure" performed + * by the \ref Log4Qt::LogManager "LogManager" on startup. If it is set to + * any other value then \c false the \ref Init "initialization procedure" + * is skipped. + * - \ref Log4Qt::LogManager::startup() "LogManager::startup()" + * + * - LOG4QT_CONFIGURATION
+ * The variable specifies the configuration file used for initialising the + * package. + * - \ref Log4Qt::LogManager::startup() "LogManager::startup()" + * + * - LOG4QT_CONFIGURATORCLASS
+ * The variable specifies the configurator class used for initialising the + * package. + * + * Environment variables are read during static initialisation on creation of + * the \ref Log4Qt::InitialisationHelper "InitialisationHelper". They can be + * accessed by calling \ref Log4Qt::InitialisationHelper::environmentSettings() + * "InitialisationHelper::environmentSettings()". + * + * All settings can also be made in the application settings under the group + * \c %Log4Qt. For example the environment variable \c LOG4QT_DEBUG is + * equivalent to the setting \c Log4Qt/Debug. If an environment variable is + * set it takes precedence over the application setting. Settings are only + * used, if an QApplication object is available, when the + * \ref Log4Qt::LogManager "LogManager" is + * initialised (see \ref Log4Qt::InitialisationHelper::setting() + * "InitialisationHelper::setting()" for details). + */ + +/*! + * \page Undocumented Undocumented functions + * + * In general it was tried to avoid the usage of undocumented features of Qt. + * Nice to have features like for example Q_DECLARE_PRIVATE are not used. Only + * features that would have been resulted in re-coding the same functionality + * are used. + * + * - QT_WA: The macro is used to call Windows A/W functions + * - \ref Log4Qt::DebugAppender "DebugAppender" + * - QBasicAtomicPointer: The class is used instead of QAtomicPointer, because + * it allows the initialisation as plain old data type. + * - \ref Log4Qt::LOG4QT_GLOBAL_STATIC "LOG4QT_GLOBAL_STATIC" + * - \ref Log4Qt::LOG4QT_IMPLEMENT_INSTANCE "LOG4QT_IMPLEMENT_INSTANCE" + * - \ref Log4Qt::LOG4QT_DECLARE_STATIC_LOGGER "LOG4QT_DECLARE_STATIC_LOGGER" + * - Q_BASIC_ATOMIC_INITIALIZER: The macro is used to initialise QAtomicPointer + * objects as plain old data type. + * - \ref Log4Qt::LOG4QT_GLOBAL_STATIC "LOG4QT_GLOBAL_STATIC" + * - \ref Log4Qt::LOG4QT_IMPLEMENT_INSTANCE "LOG4QT_IMPLEMENT_INSTANCE" + * - \ref Log4Qt::LOG4QT_DECLARE_STATIC_LOGGER "LOG4QT_DECLARE_STATIC_LOGGER" + */ + +/*! + * \page Assumptions Assumptions + * + * The following assumptions are used throughout the package: + * + * - Reading / writing of bool or int is thread-safe, if declared volatile + * - \ref Log4Qt::ListAppender "ListAppender" + * - \ref Log4Qt::AppenderSkeleton "AppenderSkeleton" + * - \ref Log4Qt::ConsoleAppender "ConsoleAppender" + * - \ref Log4Qt::FileAppender "FileAppender" + * - \ref Log4Qt::Hierarchy "Hierarchy" + * - \ref Log4Qt::Level "Level" + * - \ref Log4Qt::Logger "Logger" + * - \ref Log4Qt::WriterAppender "WriterAppender" + * - \ref Log4Qt::Layout::format() "Layout::format()" is implemented reentrant + * in all sub-classes. + * - \ref Log4Qt::AppenderSkeleton "AppenderSkeleton" + * - Being able to use singleton objects during static de-initialization without + * order issues is more valuable then their destruction. + * - \ref Log4Qt::LogManager "LogManager" + * - \ref Log4Qt::LOG4QT_GLOBAL_STATIC "LOG4QT_GLOBAL_STATIC" + * - \ref Log4Qt::LOG4QT_IMPLEMENT_INSTANCE "LOG4QT_IMPLEMENT_INSTANCE" + */ + +/****************************************************************************** + * Dependencies + ******************************************************************************/ + +#include + +#include "ukui-logmacros.h" + +#if QT_VERSION < QT_VERSION_CHECK(4, 3, 0) +# error "Log4Qt requires Qt version 4.3.0 or higher" +#endif + + +/****************************************************************************** + * Declarations + ******************************************************************************/ + +/*! + * \brief The namespace %Log4Qt encloses all parts of the package. + */ +namespace Log4Qt +{ + /*! + * This macro expands a numeric value of the form 0xMMmmPP (MM = major, + * mm = minor, PP = patch) that specifies Log4Qt's version number. + * This is the version against which the application is compiled. + * + * \sa \ref Log4Qt::LOG4QT_VERSION_STR "LOG4QT_VERSION_STR", + * \ref Log4Qt::LogManager::version() "LogManager::version()" + */ + #define LOG4QT_VERSION 0x000200 + + /*! + * The macro expands to a string that specifies the Log4Qt's version + * number. This is the version against which the application is compiled. + * + * \sa \ref Log4Qt::LOG4QT_VERSION "LOG4QT_VERSION", + * \ref Log4Qt::LogManager::version() "LogManager::version()" + */ + #define LOG4QT_VERSION_STR "0.3.0" + + enum ErrorCode + { + OK = 0, + // AppenderSkeleton, FileAppender, WriterAppender + APPENDER_ACTIVATE_MISSING_LAYOUT_ERROR, + APPENDER_ACTIVATE_MISSING_WRITER_ERROR, + APPENDER_ACTIVATE_MISSING_FILE_ERROR, + APPENDER_CLOSED_ERROR, + APPENDER_INVALID_PATTERN_ERROR, + APPENDER_NO_OPEN_FILE_ERROR, + APPENDER_NOT_ACTIVATED_ERROR, + APPENDER_OPENING_FILE_ERROR, + APPENDER_RENAMING_FILE_ERROR, + APPENDER_REMOVE_FILE_ERROR, + APPENDER_USE_INVALID_PATTERN_ERROR, + APPENDER_USE_MISSING_LAYOUT_ERROR, + APPENDER_USE_MISSING_WRITER_ERROR, + APPENDER_WRITING_FILE_ERROR, + // Level + LEVEL_INVALID_LEVEL_STRING, + // Layouts, PatternFormatter + LAYOUT_EXPECTED_DIGIT_ERROR, + LAYOUT_OPTION_IS_NOT_INTEGER_ERROR, + LAYOUT_INTEGER_IS_NOT_POSITIVE_ERROR, + // Logger + LOGGER_INVALID_LEVEL_FOR_ROOT, + // PropertyConfigurator, OptionHandler + CONFIGURATOR_OPENING_FILE_ERROR, + CONFIGURATOR_READING_FILE_ERROR, + CONFIGURATOR_INVALID_SUBSTITUTION_ERROR, + CONFIGURATOR_INVALID_OPTION_ERROR, + CONFIGURATOR_MISSING_APPENDER_ERROR, + CONFIGURATOR_UNKNOWN_APPENDER_CLASS_ERROR, + CONFIGURATOR_MISSING_LAYOUT_ERROR, + CONFIGURATOR_UNKNOWN_LAYOUT_CLASS_ERROR, + CONFIGURATOR_PROPERTY_ERROR, + CONFIGURATOR_UNKNOWN_TYPE_ERROR + }; + + + /****************************************************************************** + * Operators, Helpers + ******************************************************************************/ + + + /****************************************************************************** + * Inline + ******************************************************************************/ + + +} // namespace Log4Qt + + +#endif // LOG4QT_H diff --git a/src/log4qt/log4qt/log4qt.pri b/src/log4qt/log4qt/log4qt.pri new file mode 100644 index 0000000..f9730b9 --- /dev/null +++ b/src/log4qt/log4qt/log4qt.pri @@ -0,0 +1,111 @@ +# ******************************************************************************* +# +# package: Log4Qt +# file: log4qt.pri +# created: September 2007 +# author: Martin Heinrich +# +# +# Copyright 2007 Martin Heinrich +# +# 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. +# +# ******************************************************************************* + +INCLUDEPATH += $$PWD/.. +DEPENDPATH += $$PWD/.. +HEADERS += \ + $$PWD/appender.h \ + $$PWD/appenderskeleton.h \ + $$PWD/basicconfigurator.h \ + $$PWD/consoleappender.h \ + $$PWD/dailyrollingfileappender.h \ + $$PWD/fileappender.h \ + $$PWD/helpers/classlogger.h \ + $$PWD/helpers/configuratorhelper.h \ + $$PWD/helpers/datetime.h \ + $$PWD/helpers/factory.h \ + $$PWD/helpers/initialisationhelper.h \ + $$PWD/helpers/logerror.h \ + $$PWD/helpers/logobject.h \ + $$PWD/helpers/logobjectptr.h \ + $$PWD/helpers/optionconverter.h \ + $$PWD/helpers/patternformatter.h \ + $$PWD/helpers/properties.h \ + $$PWD/hierarchy.h \ + $$PWD/layout.h \ + $$PWD/level.h \ + $$PWD/log4qt.h \ + $$PWD/logger.h \ + $$PWD/loggerrepository.h \ + $$PWD/loggingevent.h \ + $$PWD/logmanager.h \ + $$PWD/mdc.h \ + $$PWD/ndc.h \ + $$PWD/patternlayout.h \ + $$PWD/propertyconfigurator.h \ + $$PWD/rollingfileappender.h \ + $$PWD/simplelayout.h \ + $$PWD/spi/filter.h \ + $$PWD/ttcclayout.h \ + $$PWD/writerappender.h \ + $$PWD/varia/debugappender.h \ + $$PWD/varia/denyallfilter.h \ + $$PWD/varia/nullappender.h \ + $$PWD/varia/levelmatchfilter.h \ + $$PWD/varia/levelrangefilter.h \ + $$PWD/varia/listappender.h \ + $$PWD/varia/stringmatchfilter.h + +SOURCES += \ + $$PWD/appenderskeleton.cpp \ + $$PWD/basicconfigurator.cpp \ + $$PWD/consoleappender.cpp \ + $$PWD/dailyrollingfileappender.cpp \ + $$PWD/fileappender.cpp \ + $$PWD/helpers/classlogger.cpp \ + $$PWD/helpers/configuratorhelper.cpp \ + $$PWD/helpers/datetime.cpp \ + $$PWD/helpers/factory.cpp \ + $$PWD/helpers/initialisationhelper.cpp \ + $$PWD/helpers/logerror.cpp \ + $$PWD/helpers/logobject.cpp \ + $$PWD/helpers/logobjectptr.cpp \ + $$PWD/helpers/optionconverter.cpp \ + $$PWD/helpers/patternformatter.cpp \ + $$PWD/helpers/properties.cpp \ + $$PWD/hierarchy.cpp \ + $$PWD/layout.cpp \ + $$PWD/level.cpp \ + $$PWD/log4qt.cpp \ + $$PWD/logger.cpp \ + $$PWD/loggerrepository.cpp \ + $$PWD/loggingevent.cpp \ + $$PWD/logmanager.cpp \ + $$PWD/mdc.cpp \ + $$PWD/ndc.cpp \ + $$PWD/patternlayout.cpp \ + $$PWD/propertyconfigurator.cpp \ + $$PWD/rollingfileappender.cpp \ + $$PWD/simplelayout.cpp \ + $$PWD/spi/filter.cpp \ + $$PWD/ttcclayout.cpp \ + $$PWD/writerappender.cpp \ + $$PWD/varia/debugappender.cpp \ + $$PWD/varia/denyallfilter.cpp \ + $$PWD/varia/nullappender.cpp \ + $$PWD/varia/levelmatchfilter.cpp \ + $$PWD/varia/levelrangefilter.cpp \ + $$PWD/varia/listappender.cpp \ + $$PWD/varia/stringmatchfilter.cpp + \ No newline at end of file diff --git a/src/log4qt/log4qt/logger.cpp b/src/log4qt/log4qt/logger.cpp new file mode 100644 index 0000000..d5dc936 --- /dev/null +++ b/src/log4qt/log4qt/logger.cpp @@ -0,0 +1,349 @@ +/****************************************************************************** + * + * package: Log4Qt + * file: logger.cpp + * created: September 2007 + * author: Martin Heinrich + * + * + * changes: Sep 2008, Martin Heinrich: + * - Fixed problem in Qt 4.4 where QReadWriteLock is by default + * non-recursive. + * + * + * Copyright 2007 - 2008 Martin Heinrich + * + * 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. + * + ******************************************************************************/ + + + +/****************************************************************************** + * Dependencies + ******************************************************************************/ + + +#include "log4qt/logger.h" + +#include +#include "log4qt/appenderskeleton.h" +#include "log4qt/varia/listappender.h" +#include "log4qt/loggingevent.h" +#include "log4qt/log4qt.h" +#include "log4qt/loggerrepository.h" +#include "log4qt/logmanager.h" + + +namespace Log4Qt +{ + + + /************************************************************************** + * Declarations + **************************************************************************/ + + + + /************************************************************************** + * C helper functions + **************************************************************************/ + + + + /************************************************************************** + * Class implementation: Logger + **************************************************************************/ + + + Logger::Logger(LoggerRepository* pLoggerRepository, Level level, const QString &rName, Logger *pParent) : + QObject(0), +#if QT_VERSION < QT_VERSION_CHECK(4, 4, 0) + mObjectGuard(), +#else + mObjectGuard(QReadWriteLock::Recursive), +#endif + mName(rName), + mpLoggerRepository(pLoggerRepository), + mAdditivity(true), + mAppenders(), + mLevel(level), + mpParent(pParent) + { + Q_ASSERT_X(pLoggerRepository, "Logger::Logger()", "Construction of Logger with null LoggerRepository"); + + setObjectName(mName); + } + + + Logger::~Logger() + { + logger()->warn("Unexpected destruction of Logger"); + + // QWriteLocker locker(&mObjectGuard); + // + // QMutableListIterator< LogObjectPtr > i(mAppenders); + // while (i.hasNext()) + // { + // i.next(); + // i.remove(); + // } + } + + + QList Logger::appenders() const + { + QReadLocker locker(&mObjectGuard); + + QList result; + Appender *p_appender; + Q_FOREACH(p_appender, mAppenders) + result << p_appender; + return result; + } + + + void Logger::setLevel(Level level) + { + // QWriteLocker locker(&mObjectGuard); // Read/Write int is safe + + if ((parentLogger() == 0) && (level == Level::NULL_INT)) + { + logger()->warn("Invalid root logger level NULL_INT. Using DEBUG_INT instead"); + level = Level::DEBUG_INT; + } + mLevel = level; + } + + + void Logger::addAppender(Appender *pAppender) + { + // Avoid deadlock: + // - Handle warnings, before write lock is aquired + + // Keep objects with a 0 reference count safe + LogObjectPtr p_appender = pAppender; + + { + QReadLocker locker(&mObjectGuard); + + if(!p_appender) + { + logger()->warn("Adding null Appender to Logger '%1'", name()); + return; + } + if(mAppenders.contains(p_appender)) + { + logger()->warn("Adding of duplicate appender '%2' to logger '%1'", name(), p_appender->name()); + return; + } + } + { + QWriteLocker locker(&mObjectGuard); + + if(mAppenders.contains(p_appender)) + return; + mAppenders.append(p_appender); + } + } + + + Appender *Logger::appender(const QString &rName) const + { + QReadLocker locker(&mObjectGuard); + + Appender *p_appender; + Q_FOREACH(p_appender, mAppenders) + if (p_appender->name() == rName) + return p_appender; + return 0; + } + + + + void Logger::callAppenders(const LoggingEvent &rEvent) const + { + QReadLocker locker(&mObjectGuard); + + Appender *p_appender; + Q_FOREACH(p_appender, mAppenders) + p_appender->doAppend(rEvent); + if (additivity() && (parentLogger() != 0)) + parentLogger()->callAppenders(rEvent); + } + + + bool Logger::isAttached(Appender *pAppender) const + { + QReadLocker locker(&mObjectGuard); + + // Keep objects with a 0 reference count safe + LogObjectPtr p_appender = pAppender; + + return mAppenders.contains(p_appender); + } + + + void Logger::removeAllAppenders() + { + // Avoid deadlock: + // - Only log warnings without having the write log aquired + // - Hold a reference to all appenders so that the remove does not + // destruct the appender over the reference count while the write + // log is held. The appender may log messages. + + logger()->trace("Removing all appenders from logger '%1'", name()); + + QList< LogObjectPtr > appenders; + { + QWriteLocker locker(&mObjectGuard); + QMutableListIterator< LogObjectPtr > i(mAppenders); + while (i.hasNext()) + { + Appender *p_appender = i.next(); + ListAppender *p_listappender = qobject_cast(p_appender); + if (p_listappender && p_listappender->configuratorList()) + continue; + else + { + appenders << p_appender; + i.remove(); + } + } + } + appenders.clear(); + } + + + void Logger::removeAppender(Appender *pAppender) + { + // Avoid deadlock: + // - Only log warnings without having the write log aquired + // - Hold a reference to the appender so that the remove does not + // destruct the appender over the reference count while the write + // log is held. The appender may log messages. + + LogObjectPtr p_appender = pAppender; + + if(!p_appender) + { + logger()->warn("Request to remove null Appender from Logger '%1'", name()); + return; + } + int n; + { + QWriteLocker locker(&mObjectGuard); + + n = mAppenders.removeAll(p_appender); + } + if (n == 0) + { + logger()->warn("Request to remove Appender '%2', which is not part of Logger '%1' appenders", name(), p_appender->name()); + return; + } + } + + + void Logger::removeAppender(const QString &rName) + { + Appender *p_appender = appender(rName); + if (p_appender) + removeAppender(p_appender); + } + + + Level Logger::effectiveLevel() const + { + Q_ASSERT_X(LogManager::rootLogger()->level() != Level::NULL_INT, "Logger::effectiveLevel()", "Root logger level must not be NULL_INT"); + + QReadLocker locker(&mObjectGuard); + + const Logger *p_logger = this; + while (p_logger->level() == Level::NULL_INT) + p_logger = p_logger->parentLogger(); + return p_logger->level(); + } + + + bool Logger::isEnabledFor(Level level) const + { + if (mpLoggerRepository->isDisabled(level)) + return false; + return (effectiveLevel() <= level); + } + + + Logger *Logger::logger(const QString &rName) + { + return LogManager::logger(rName); + } + + + Logger *Logger::logger(const char *pName) + { + return LogManager::logger(QLatin1String(pName)); + } + + + Logger *Logger::rootLogger() + { + return LogManager::rootLogger(); + } + + +#ifndef QT_NO_DEBUG_STREAM + QDebug Logger::debug(QDebug &rDebug) const + { + QReadLocker locker(&mObjectGuard); + + QString parent_logger; + if (mpParent) + parent_logger = mpParent->name(); + + rDebug.nospace() << "Logger(" + << "name:" << name() << " " + << "appenders:" << mAppenders.count() << " " + << "additivity:" << mAdditivity << " " + << mLevel + << "parentLogger:" << parent_logger + << ")"; + return rDebug.space(); + } +#endif // QT_NO_DEBUG_STREAM + + + void Logger::forcedLog(Level level, const QString &rMessage) const + { + QReadLocker locker(&mObjectGuard); + + LoggingEvent event(this, level, rMessage); + callAppenders(event); + } + + + + /************************************************************************** + * Implementation: Operators, Helper + **************************************************************************/ + + +#ifndef QT_NO_DEBUG_STREAM + QDebug operator<<(QDebug debug, const Logger &rLogger) + { + return rLogger.debug(debug); + } +#endif // QT_NO_DEBUG_STREAM + + + +} // namespace Log4Qt diff --git a/src/log4qt/log4qt/logger.h b/src/log4qt/log4qt/logger.h new file mode 100644 index 0000000..73a877d --- /dev/null +++ b/src/log4qt/log4qt/logger.h @@ -0,0 +1,1666 @@ +/****************************************************************************** + * + * package: Log4Qt + * file: logger.h + * created: September 2007 + * author: Martin Heinrich + * + * + * changes: Sep 2008, Martin Heinrich: + * - Replaced usage of q_atomic_test_and_set_ptr with + * QBasicAtomicPointer + * + * + * Copyright 2007 - 2008 Martin Heinrich + * + * 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. + * + ******************************************************************************/ + +#ifndef LOG4QT_LOGGER_H +#define LOG4QT_LOGGER_H + + +/****************************************************************************** + * Dependencies + ******************************************************************************/ + +#include + +#include +#include +#include +#include "log4qt/helpers/logerror.h" +#include "log4qt/helpers/classlogger.h" +#include "log4qt/helpers/logobjectptr.h" +#include "log4qt/level.h" +#include "ukui-logmacros.h" + +#if QT_VERSION >= QT_VERSION_CHECK(4, 4, 0) +# ifndef Q_ATOMIC_POINTER_TEST_AND_SET_IS_ALWAYS_NATIVE +# warning "QAtomicPointer test and set is not native. The macro Log4Qt::LOG4QT_DECLARE_STATIC_LOGGER is not thread-safe." +# endif +#endif + + +/****************************************************************************** + * Declarations + ******************************************************************************/ + +namespace Log4Qt +{ + + /*! + * LOG4QT_DECLARE_STATIC_LOGGER declares a static function \a FUNCTION that + * returns a pointer to a \ref Log4Qt::Logger "Logger" named after \a CLASS. + * + * On the first invocation the \ref Log4Qt::Logger "Logger" is requested + * by calling \ref Log4Qt::Logger::logger(const char *pName) + * "Logger::logger( #CLASS )". The pointer is stored to be returned on + * subsequent invocations. + * + * The following example shows how to use the macro to define a logger to be + * used within a class not derived from QObject. + * + * \code + * #file: counter.h + * + * #include logger.h + * + * class Counter + * { + * public: + * Counter(); + * Counter(int preset); + * private: + * int mCount; + * } + * \endcode + * \code + * #file: counter.cpp + * + * #include counter.h + * + * LOG4QT_DECLARE_STATIC_LOGGER(logger, Counter) + * + * Counter::Counter() : + * mCount(0) + * {} + * + * void Counter::Counter(int preset) : + * mCount(preset) + * { + * if (preset < 0) + * { + * logger()->warn("Invalid negative counter preset %1. Using 0 instead.", preset); + * mCount = 0; + * } + * } + * \endcode + * + * \note The function created by the macro is thread-safe. + * + * \sa \ref Log4Qt::Logger::logger(const char *pName) "Logger::logger(const char *pName)" + */ +#if QT_VERSION < QT_VERSION_CHECK(4, 4, 0) + #define LOG4QT_DECLARE_STATIC_LOGGER(FUNCTION, CLASS) \ + static Log4Qt::Logger *FUNCTION() \ + { \ + static Log4Qt::Logger *p_logger = 0; \ + if (!p_logger) \ + { \ + q_atomic_test_and_set_ptr( \ + &p_logger, \ + 0, \ + Log4Qt::Logger::logger( #CLASS )); \ + } \ + return p_logger; \ + } +#elif QT_VERSION < QT_VERSION_CHECK(5, 0, 0) + #define LOG4QT_DECLARE_STATIC_LOGGER(FUNCTION, CLASS) \ + static Log4Qt::Logger *FUNCTION() \ + { \ + static QBasicAtomicPointer p_logger = \ + Q_BASIC_ATOMIC_INITIALIZER(0); \ + if (!p_logger) \ + { \ + p_logger.testAndSetOrdered(0, \ + Log4Qt::Logger::logger( #CLASS )); \ + } \ + return p_logger; \ + } +#else + #define LOG4QT_DECLARE_STATIC_LOGGER(FUNCTION, CLASS) \ + static Log4Qt::Logger *FUNCTION() \ + { \ + static QBasicAtomicPointer p_logger = \ + Q_BASIC_ATOMIC_INITIALIZER(0); \ + if (!p_logger.loadAcquire()) \ + { \ + p_logger.testAndSetOrdered(0, \ + Log4Qt::Logger::logger( #CLASS )); \ + } \ + return p_logger.loadAcquire(); \ + } +#endif + + /*! + * LOG4QT_DECLARE_QCLASS_LOGGER declares member functions to retrieve + * \ref Log4Qt::Logger "Logger" for the class it is used in. + * + * On the first invocation the \ref Log4Qt::Logger "Logger" is requested + * by a call to \ref Log4Qt::Logger::logger(const char *pName) + * "Logger::logger(const char *pName)". The pointer is stored to be + * returned on subsequent invocations. + * + * The following example shows how to use the macro to define a logger to be + * used within a class derived from QObject. + * + * \code + * #file: counter.h + * + * #include qobject.h + * #include logger.h + * + * class Counter : public QObject + * { + * Q_OBJECT + * LOG4QT_DECLARE_QCLASS_LOGGER + * public: + * Counter(); + * Counter(int preset); + * private: + * int mCount; + * } + * \endcode + * \code + * #file: counter.cpp + * + * #include counter.h + * + * Counter::Counter() : + * mCount(0) + * {} + * + * void Counter::Counter(int preset) + * mCount(preset) + * { + * if (preset < 0) + * { + * logger()->warn("Invalid negative counter preset %1. Using 0 instead.", preset); + * mCount = 0; + * } + * } + * \endcode + * + * \note The function created by the macro is thread-safe. + * + * \sa \ref Log4Qt::Logger::logger(const char *pName) "Logger::logger(const char *pName)", + * \ref Log4Qt::ClassLogger "ClassLogger" + */ + #define LOG4QT_DECLARE_QCLASS_LOGGER \ + private: \ + mutable Log4Qt::ClassLogger mLog4QtClassLogger; \ + public: \ + inline Log4Qt::Logger *logger() const \ + { return mLog4QtClassLogger.logger(this); } \ + private: + + class Appender; + class LoggingEvent; + class LoggerRepository; + + /*! + * \brief The class Logger provides logging services. + * + * A pointer to a logger can be retrieved by calling Logger::logger() or + * LogManager::logger() with the class name as argument. Because a logger + * is never destroyed it is possible to store the pointer to the logger. + * This way the lookup of the pointer in the repository is only required + * on the first logging operation. The macros \ref + * Log4Qt::LOG4QT_DECLARE_STATIC_LOGGER "LOG4QT_DECLARE_STATIC_LOGGER" and + * \ref Log4Qt::LOG4QT_DECLARE_QCLASS_LOGGER "LOG4QT_DECLARE_QCLASS_LOGGER" + * provide a thread-safe implementation to store the logger pointer. + * + * \note All the functions declared in this class are thread-safe. + */ + class LIBUKUILOG4QT_EXPORT Logger : public QObject + { + Q_OBJECT + + /*! + * The property holds, if the logger is additive. + * + * The default is true for being additive. + * + * \sa additive(), setAdditive() + */ + Q_PROPERTY(bool additivity READ additivity WRITE setAdditivity) + + /*! + * The property holds the level used by the logger. + * + * The default is Level::NULL_INT. + * \sa level(), setLevel() + */ + Q_PROPERTY(Level level READ level WRITE setLevel) + + /*! + * The property holds the LoggerRepository of the logger. + * + * \sa loggerRepository() + */ + Q_PROPERTY(LoggerRepository* loggerRepository READ loggerRepository) + + /*! + * The property holds the name of the logger. + * + * \sa name() + */ + Q_PROPERTY(QString name READ name) + + /*! + * The property holds the parent logger of the logger. + * + * \sa parentLogger() + */ + Q_PROPERTY(Logger* parentLogger READ parentLogger) + + LOG4QT_DECLARE_QCLASS_LOGGER + + protected: + Logger(LoggerRepository* pLoggerRepository, Level level, const QString &rName, Logger *pParent = 0); + virtual ~Logger(); + private: + Logger(const Logger &rOther); // Not implemented + Logger &operator=(const Logger &rOther); // Not implemented + + public: + bool additivity() const; + QList appenders() const; + Level level() const; + LoggerRepository *loggerRepository() const; + QString name() const; + Logger *parentLogger() const; + // JAVA: ResourceBundle *resourceBundle() const; + // JAVA: void setResourceBundle(ResourceBundle *pResourceBundle); + void setAdditivity(bool additivity); + virtual void setLevel(Level level); + + void addAppender(Appender *pAppender); + Appender *appender(const QString &rName) const; + void callAppenders(const LoggingEvent &rEvent) const; + bool isAttached(Appender *pAppender) const; + + /*! + * Removes all appenders that have been previously added from this + * Logger. + * + * To allow configurators to collect events during the configuration + * process ListAppenders with the configuratorList property set, will + * not be removed. + * + * \sa LisAppender::setConfiguratorList() + */ + void removeAllAppenders(); + + void removeAppender(Appender *pAppender); + void removeAppender(const QString &rName); + // JAVA: QString resourceBundleString(const QString &rKey) const; + + Level effectiveLevel() const; + bool isDebugEnabled() const; + + /*! + * Checks if this logger is enabled for a given Level \a level. If the + * logger is enabled the function returns true. Otherwise it returns + * false. + * + * A logger is enabled for a level, if the level is greater or equal + * then the repository threshold and greater and equal then the loggers + * effective level. + * + * \sa LoggerRepository::isDisabled(), effectiveLevel() + */ + bool isEnabledFor(Level level) const; + + bool isErrorEnabled() const; + bool isFatalEnabled() const; + bool isInfoEnabled() const; + bool isTraceEnabled() const; + bool isWarnEnabled() const; + + void debug(const QString &rMessage) const; + void debug(const LogError &rLogError) const; + void debug(const char *pMessage) const; + void debug(const char *pMessage, + const QString &rArg1) const; + void debug(const char *pMessage, + int arg1) const; + void debug(const char *pMessage, + const QString &rArg1, + const QString &rArg2) const; + void debug(const char *pMessage, + const QString &rArg1, + int arg2) const; + void debug(const char *pMessage, + int arg1, + const QString &rArg2) const; + void debug(const char *pMessage, + int arg1, + int arg2) const; + void debug(const char *pMessage, + const QString &rArg1, + const QString &rArg2, + const QString &rArg3) const; + void debug(const char *pMessage, + const QString &rArg1, + const QString &rArg2, + int arg3) const; + void debug(const char *pMessage, + const QString &rArg1, + int arg2, + const QString &rArg3) const; + void debug(const char *pMessage, + const QString &rArg1, + int arg2, + int arg3) const; + void debug(const char *pMessage, + int arg1, + const QString &rArg2, + const QString &rArg3) const; + void debug(const char *pMessage, + int arg1, + const QString &rArg2, + int arg3) const; + void debug(const char *pMessage, + int arg1, + int arg2, + const QString &rArg3) const; + void debug(const char *pMessage, + int arg1, + int arg2, + int arg3) const; + void debug(const char *pMessage, + const QVariant &rArg1, + const QVariant &rArg2, + const QVariant &rArg3) const; + + void error(const QString &rMessage) const; + void error(const LogError &rLogError) const; + void error(const char *pMessage) const; + void error(const char *pMessage, + const QString &rArg1) const; + void error(const char *pMessage, + int arg1) const; + void error(const char *pMessage, + const QString &rArg1, + const QString &rArg2) const; + void error(const char *pMessage, + const QString &rArg1, int arg2) const; + void error(const char *pMessage, + int arg1, + const QString &rArg2) const; + void error(const char *pMessage, + int arg1, + int arg2) const; + void error(const char *pMessage, + const QString &rArg1, + const QString &rArg2, + const QString &rArg3) const; + void error(const char *pMessage, + const QString &rArg1, + const QString &rArg2, + int arg3) const; + void error(const char *pMessage, + const QString &rArg1, + int arg2, + const QString &rArg3) const; + void error(const char *pMessage, + const QString &rArg1, + int arg2, + int arg3) const; + void error(const char *pMessage, + int arg1, + const QString &rArg2, + const QString &rArg3) const; + void error(const char *pMessage, + int arg1, + const QString &rArg2, + int arg3) const; + void error(const char *pMessage, + int arg1, + int arg2, + const QString &rArg3) const; + void error(const char *pMessage, + int arg1, + int arg2, + int arg3) const; + void error(const char *pMessage, + const QVariant &rArg1, + const QVariant &rArg2, + const QVariant &rArg3) const; + + void fatal(const QString &rMessage) const; + void fatal(const LogError &rLogError) const; + void fatal(const char *pMessage) const; + void fatal(const char *pMessage, + const QString &rArg1) const; + void fatal(const char *pMessage, + int arg1) const; + void fatal(const char *pMessage, + const QString &rArg1, + const QString &rArg2) const; + void fatal(const char *pMessage, + const QString &rArg1, + int arg2) const; + void fatal(const char *pMessage, + int arg1, + const QString &rArg2) const; + void fatal(const char *pMessage, + int arg1, + int arg2) const; + void fatal(const char *pMessage, + const QString &rArg1, + const QString &rArg2, + const QString &rArg3) const; + void fatal(const char *pMessage, + const QString &rArg1, + const QString &rArg2, + int arg3) const; + void fatal(const char *pMessage, + const QString &rArg1, + int arg2, + const QString &rArg3) const; + void fatal(const char *pMessage, + const QString &rArg1, + int arg2, + int arg3) const; + void fatal(const char *pMessage, + int arg1, + const QString &rArg2, + const QString &rArg3) const; + void fatal(const char *pMessage, + int arg1, + const QString &rArg2, + int arg3) const; + void fatal(const char *pMessage, + int arg1, + int arg2, + const QString &rArg3) const; + void fatal(const char *pMessage, + int arg1, + int arg2, + int arg3) const; + void fatal(const char *pMessage, + const QVariant &rArg1, + const QVariant &rArg2, + const QVariant &rArg3) const; + + void info(const QString &rMessage) const; + void info(const LogError &rLogError) const; + void info(const char *pMessage) const; + void info(const char *pMessage, + const QString &rArg1) const; + void info(const char *pMessage, + int arg1) const; + void info(const char *pMessage, + const QString &rArg1, + const QString &rArg2) const; + void info(const char *pMessage, + const QString &rArg1, + int arg2) const; + void info(const char *pMessage, + int arg1, + const QString &rArg2) const; + void info(const char *pMessage, + int arg1, + int arg2) const; + void info(const char *pMessage, + const QString &rArg1, + const QString &rArg2, + const QString &rArg3) const; + void info(const char *pMessage, + const QString &rArg1, + const QString &rArg2, + int arg3) const; + void info(const char *pMessage, + const QString &rArg1, + int arg2, + const QString &rArg3) const; + void info(const char *pMessage, + const QString &rArg1, + int arg2, + int arg3) const; + void info(const char *pMessage, + int arg1, + const QString &rArg2, + const QString &rArg3) const; + void info(const char *pMessage, + int arg1, + const QString &rArg2, + int arg3) const; + void info(const char *pMessage, + int arg1, + int arg2, + const QString &rArg3) const; + void info(const char *pMessage, + int arg1, + int arg2, + int arg3) const; + void info(const char *pMessage, + const QVariant &rArg1, + const QVariant &rArg2, + const QVariant &rArg3) const; + + void log(Level level, + const QString &rMessage) const; + void log(Level level, + const LogError &rLogError) const; + void log(Level level, + const char *pMessage) const; + void log(Level level, + const char *pMessage, + const QString &rArg1) const; + void log(Level level, + const char *pMessage, + int arg1) const; + void log(Level level, + const char *pMessage, + const QString &rArg1, + const QString &rArg2) const; + void log(Level level, + const char *pMessage, + const QString &rArg1, + int arg2) const; + void log(Level level, + const char *pMessage, + int arg1, + const QString &rArg2) const; + void log(Level level, + const char *pMessage, + int arg1, + int arg2) const; + void log(Level level, + const char *pMessage, + const QString &rArg1, + const QString &rArg2, + const QString &rArg3) const; + void log(Level level, + const char *pMessage, + const QString &rArg1, + const QString &rArg2, + int arg3) const; + void log(Level level, + const char *pMessage, + const QString &rArg1, + int arg2, + const QString &rArg3) const; + void log(Level level, + const char *pMessage, + const QString &rArg1, + int arg2, + int arg3) const; + void log(Level level, + const char *pMessage, + int arg1, + const QString &rArg2, + const QString &rArg3) const; + void log(Level level, + const char *pMessage, + int arg1, + const QString &rArg2, + int arg3) const; + void log(Level level, + const char *pMessage, + int arg1, + int arg2, + const QString &rArg3) const; + void log(Level level, + const char *pMessage, + int arg1, + int arg2, + int arg3) const; + void log(Level level, + const char *pMessage, + const QVariant &rArg1, + const QVariant &rArg2, + const QVariant &rArg3) const; + + // JAVA: void l7dlog(Level level, + // const QString &rKey); + // JAVA: void l7dlog(Level level, + // const QString &rKey, + // const QList rParameters); + + void trace(const QString &rMessage) const; + void trace(const LogError &rLogError) const; + void trace(const char *pMessage) const; + void trace(const char *pMessage, + const QString &rArg1) const; + void trace(const char *pMessage, + int arg1) const; + void trace(const char *pMessage, + const QString &rArg1, + const QString &rArg2) const; + void trace(const char *pMessage, + const QString &rArg1, + int arg2) const; + void trace(const char *pMessage, + int arg1, + const QString &rArg2) const; + void trace(const char *pMessage, + int arg1, + int arg2) const; + void trace(const char *pMessage, + const QString &rArg1, + const QString &rArg2, + const QString &rArg3) const; + void trace(const char *pMessage, + const QString &rArg1, + const QString &rArg2, + int arg3) const; + void trace(const char *pMessage, + const QString &rArg1, + int arg2, + const QString &rArg3) const; + void trace(const char *pMessage, + const QString &rArg1, + int arg2, + int arg3) const; + void trace(const char *pMessage, + int arg1, + const QString &rArg2, + const QString &rArg3) const; + void trace(const char *pMessage, + int arg1, + const QString &rArg2, + int arg3) const; + void trace(const char *pMessage, + int arg1, + int arg2, + const QString &rArg3) const; + void trace(const char *pMessage, + int arg1, + int arg2, + int arg3) const; + void trace(const char *pMessage, + const QVariant &rArg1, + const QVariant &rArg2, + const QVariant &rArg3) const; + + void warn(const QString &rMessage) const; + void warn(const LogError &rLogError) const; + void warn(const char *pMessage) const; + void warn(const char *pMessage, + const QString &rArg1) const; + void warn(const char *pMessage, + int arg1) const; + void warn(const char *pMessage, + const QString &rArg1, + const QString &rArg2) const; + void warn(const char *pMessage, + const QString &rArg1, + int arg2) const; + void warn(const char *pMessage, + int arg1, + const QString &rArg2) const; + void warn(const char *pMessage, + int arg1, + int arg2) const; + void warn(const char *pMessage, + const QString &rArg1, + const QString &rArg2, + const QString &rArg3) const; + void warn(const char *pMessage, + const QString &rArg1, + const QString &rArg2, + int arg3) const; + void warn(const char *pMessage, + const QString &rArg1, + int arg2, + const QString &rArg3) const; + void warn(const char *pMessage, + const QString &rArg1, + int arg2, + int arg3) const; + void warn(const char *pMessage, + int arg1, + const QString &rArg2, + const QString &rArg3) const; + void warn(const char *pMessage, + int arg1, + const QString &rArg2, + int arg3) const; + void warn(const char *pMessage, + int arg1, + int arg2, + const QString &rArg3) const; + void warn(const char *pMessage, + int arg1, + int arg2, + int arg3) const; + void warn(const char *pMessage, + const QVariant &rArg1, + const QVariant &rArg2, + const QVariant &rArg3) const; + + // LogManager operations + static Logger *logger(const QString &rName); + static Logger *logger(const char *pName); + static Logger *rootLogger(); + + protected: +#ifndef QT_NO_DEBUG_STREAM + /*! + * Writes all object member variables to the given debug stream \a rDebug + * and returns the stream. + * + * + * %Logger(name:"Log4Qt" appenders:0 additivity:true Level("NULL") + * parentLogger: "root" ) + * + * \sa QDebug, operator<<(QDebug debug, const Appender &rAppender) + */ + virtual QDebug debug(QDebug &rDebug) const; + friend QDebug operator<<(QDebug debug, + const Logger &rLogger); +#endif // QT_NO_DEBUG_STREAM + + void forcedLog(Level level, + const QString &rMessage) const; + + protected: + mutable QReadWriteLock mObjectGuard; + private: + const QString mName; + LoggerRepository* mpLoggerRepository; + volatile bool mAdditivity; + QList< LogObjectPtr > mAppenders; + Level mLevel; + Logger *mpParent; + + // Needs to be friend to create Logger objects + friend class Hierarchy; + }; + + + /****************************************************************************** + * Operators, Helper + ******************************************************************************/ + +#ifndef QT_NO_DEBUG_STREAM + /*! + * \relates Logger + * + * Writes all object member variables to the given debug stream \a debug and + * returns the stream. + * + * To handle subclassing the function uses the virtual member function debug(). + * This allows each class to generate its own output. + * + * \sa QDebug, debug() + */ + QDebug operator<<(QDebug debug, + const Logger &rLogger); +#endif // QT_NO_DEBUG_STREAM + + + /************************************************************************** + * Inline + **************************************************************************/ + + inline bool Logger::additivity() const + { // QReadLocker locker(&mObjectGuard); // Read/Write of int is safe + return mAdditivity; } + + inline Level Logger::level() const + { // QReadLocker locker(&mObjectGuard); // Level is thread-safe + return mLevel; } + + inline LoggerRepository *Logger::loggerRepository() const + { // QReadLocker locker(&mObjectGuard); // Constant for object lifetime + return mpLoggerRepository; } + + inline QString Logger::name() const + { // QReadLocker locker(&mObjectGuard); // Constant for object lifetime + return mName; } + + inline Logger *Logger::parentLogger() const + { // QReadLocker locker(&mObjectGuard); // Constant for object lifetime + return mpParent; } + + inline void Logger::setAdditivity(bool additivity) + { // QWriteLocker locker(&mObjectGuard); // Read/Write of int is safe + mAdditivity = additivity; } + + // Level operations + + inline bool Logger::isDebugEnabled() const + { return isEnabledFor(Level::DEBUG_INT); } + + inline bool Logger::isErrorEnabled() const + { return isEnabledFor(Level::ERROR_INT); } + + inline bool Logger::isFatalEnabled() const + { return isEnabledFor(Level::FATAL_INT); } + + inline bool Logger::isInfoEnabled() const + { return isEnabledFor(Level::INFO_INT); } + + inline bool Logger::isTraceEnabled() const + { return isEnabledFor(Level::TRACE_INT); } + + inline bool Logger::isWarnEnabled() const + { return isEnabledFor(Level::WARN_INT); } + + // Log operations: debug + + inline void Logger::debug(const LogError &rLogError) const + { if (isEnabledFor(Level::DEBUG_INT)) + forcedLog(Level::DEBUG_INT, rLogError.toString()); } + + inline void Logger::debug(const QString &rMessage) const + { if (isEnabledFor(Level::DEBUG_INT)) + forcedLog(Level::DEBUG_INT, rMessage); } + + inline void Logger::debug(const char *pMessage) const + { if (isEnabledFor(Level::DEBUG_INT)) + forcedLog(Level::DEBUG_INT, QString::fromUtf8(pMessage)); } + + inline void Logger::debug(const char *pMessage, + const QString &rArg1) const + { if (isEnabledFor(Level::DEBUG_INT)) + forcedLog(Level::DEBUG_INT, QString::fromUtf8(pMessage).arg(rArg1)); } + + inline void Logger::debug(const char *pMessage, + int arg1) const + { if (isEnabledFor(Level::DEBUG_INT)) + forcedLog(Level::DEBUG_INT, QString::fromUtf8(pMessage).arg(arg1)); } + + inline void Logger::debug(const char *pMessage, + const QString &rArg1, + const QString &rArg2) const + { if (isEnabledFor(Level::DEBUG_INT)) + forcedLog(Level::DEBUG_INT, QString::fromUtf8(pMessage).arg(rArg1, rArg2)); } + + inline void Logger::debug(const char *pMessage, + const QString &rArg1, + int arg2) const + { if (isEnabledFor(Level::DEBUG_INT)) + forcedLog(Level::DEBUG_INT, QString::fromUtf8(pMessage).arg(rArg1).arg(arg2)); } + + inline void Logger::debug(const char *pMessage, + int arg1, + const QString &rArg2) const + { if (isEnabledFor(Level::DEBUG_INT)) + forcedLog(Level::DEBUG_INT, QString::fromUtf8(pMessage).arg(arg1).arg(rArg2)); } + + inline void Logger::debug(const char *pMessage, + int arg1, + int arg2) const + { if (isEnabledFor(Level::DEBUG_INT)) + forcedLog(Level::DEBUG_INT, QString::fromUtf8(pMessage).arg(arg1).arg(arg2)); } + + inline void Logger::debug(const char *pMessage, + const QString &rArg1, + const QString &rArg2, + const QString &rArg3) const + { if (isEnabledFor(Level::DEBUG_INT)) + forcedLog(Level::DEBUG_INT, QString::fromUtf8(pMessage).arg(rArg1, rArg2, rArg3)); } + + inline void Logger::debug(const char *pMessage, + const QString &rArg1, + const QString &rArg2, + int arg3) const + { if (isEnabledFor(Level::DEBUG_INT)) + forcedLog(Level::DEBUG_INT, QString::fromUtf8(pMessage).arg(rArg1, rArg2).arg(arg3)); } + + inline void Logger::debug(const char *pMessage, + const QString &rArg1, + int arg2, + const QString &rArg3) const + { if (isEnabledFor(Level::DEBUG_INT)) + forcedLog(Level::DEBUG_INT, QString::fromUtf8(pMessage).arg(rArg1).arg(arg2).arg(rArg3)); } + + inline void Logger::debug(const char *pMessage, + const QString &rArg1, + int arg2, + int arg3) const + { if (isEnabledFor(Level::DEBUG_INT)) + forcedLog(Level::DEBUG_INT, QString::fromUtf8(pMessage).arg(rArg1).arg(arg2).arg(arg3)); } + + inline void Logger::debug(const char *pMessage, + int arg1, + const QString &rArg2, + const QString &rArg3) const + { if (isEnabledFor(Level::DEBUG_INT)) + forcedLog(Level::DEBUG_INT, QString::fromUtf8(pMessage).arg(arg1).arg(rArg2).arg(rArg3)); } + + inline void Logger::debug(const char *pMessage, + int arg1, + const QString &rArg2, + int arg3) const + { if (isEnabledFor(Level::DEBUG_INT)) + forcedLog(Level::DEBUG_INT, QString::fromUtf8(pMessage).arg(arg1).arg(rArg2).arg(arg3)); } + + inline void Logger::debug(const char *pMessage, + int arg1, + int arg2, + const QString &rArg3) const + { if (isEnabledFor(Level::DEBUG_INT)) + forcedLog(Level::DEBUG_INT, QString::fromUtf8(pMessage).arg(arg1).arg(arg2).arg(rArg3)); } + + inline void Logger::debug(const char *pMessage, + int arg1, + int arg2, + int arg3) const + { if (isEnabledFor(Level::DEBUG_INT)) + forcedLog(Level::DEBUG_INT, QString::fromUtf8(pMessage).arg(arg1).arg(arg2).arg(arg3)); } + + inline void Logger::debug(const char *pMessage, + const QVariant &rArg1, + const QVariant &rArg2, + const QVariant &rArg3) const + { if (isEnabledFor(Level::DEBUG_INT)) + forcedLog(Level::DEBUG_INT, QString::fromUtf8(pMessage).arg(rArg1.toString(), rArg2.toString(), rArg3.toString())); } + + // Log operations: error + + inline void Logger::error(const QString &rMessage) const + { if (isEnabledFor(Level::ERROR_INT)) + forcedLog(Level::ERROR_INT, rMessage); } + + inline void Logger::error(const LogError &rLogError) const + { if (isEnabledFor(Level::ERROR_INT)) + forcedLog(Level::ERROR_INT, rLogError.toString()); } + + inline void Logger::error(const char *pMessage) const + { if (isEnabledFor(Level::ERROR_INT)) + forcedLog(Level::ERROR_INT, QString::fromUtf8(pMessage)); } + + inline void Logger::error(const char *pMessage, + const QString &rArg1) const + { if (isEnabledFor(Level::ERROR_INT)) + forcedLog(Level::ERROR_INT, QString::fromUtf8(pMessage).arg(rArg1)); } + + inline void Logger::error(const char *pMessage, + int arg1) const + { if (isEnabledFor(Level::ERROR_INT)) + forcedLog(Level::ERROR_INT, QString::fromUtf8(pMessage).arg(arg1)); } + + inline void Logger::error(const char *pMessage, + const QString &rArg1, + const QString &rArg2) const + { if (isEnabledFor(Level::ERROR_INT)) + forcedLog(Level::ERROR_INT, QString::fromUtf8(pMessage).arg(rArg1, rArg2)); } + + inline void Logger::error(const char *pMessage, + const QString &rArg1, + int arg2) const + { if (isEnabledFor(Level::ERROR_INT)) + forcedLog(Level::ERROR_INT, QString::fromUtf8(pMessage).arg(rArg1).arg(arg2)); } + + inline void Logger::error(const char *pMessage, + int arg1, + const QString &rArg2) const + { if (isEnabledFor(Level::ERROR_INT)) + forcedLog(Level::ERROR_INT, QString::fromUtf8(pMessage).arg(arg1).arg(rArg2)); } + + inline void Logger::error(const char *pMessage, + int arg1, + int arg2) const + { if (isEnabledFor(Level::ERROR_INT)) + forcedLog(Level::ERROR_INT, QString::fromUtf8(pMessage).arg(arg1).arg(arg2)); } + + inline void Logger::error(const char *pMessage, + const QString &rArg1, + const QString &rArg2, + const QString &rArg3) const + { if (isEnabledFor(Level::ERROR_INT)) + forcedLog(Level::ERROR_INT, QString::fromUtf8(pMessage).arg(rArg1, rArg2, rArg3)); } + + inline void Logger::error(const char *pMessage, + const QString &rArg1, + const QString &rArg2, + int arg3) const + { if (isEnabledFor(Level::ERROR_INT)) + forcedLog(Level::ERROR_INT, QString::fromUtf8(pMessage).arg(rArg1, rArg2).arg(arg3)); } + + inline void Logger::error(const char *pMessage, + const QString &rArg1, + int arg2, + const QString &rArg3) const + { if (isEnabledFor(Level::ERROR_INT)) + forcedLog(Level::ERROR_INT, QString::fromUtf8(pMessage).arg(rArg1).arg(arg2).arg(rArg3)); } + + inline void Logger::error(const char *pMessage, + const QString &rArg1, + int arg2, + int arg3) const + { if (isEnabledFor(Level::ERROR_INT)) + forcedLog(Level::ERROR_INT, QString::fromUtf8(pMessage).arg(rArg1).arg(arg2).arg(arg3)); } + + inline void Logger::error(const char *pMessage, + int arg1, + const QString &rArg2, + const QString &rArg3) const + { if (isEnabledFor(Level::ERROR_INT)) + forcedLog(Level::ERROR_INT, QString::fromUtf8(pMessage).arg(arg1).arg(rArg2).arg(rArg3)); } + + inline void Logger::error(const char *pMessage, + int arg1, + const QString &rArg2, + int arg3) const + { if (isEnabledFor(Level::ERROR_INT)) + forcedLog(Level::ERROR_INT, QString::fromUtf8(pMessage).arg(arg1).arg(rArg2).arg(arg3)); } + + inline void Logger::error(const char *pMessage, + int arg1, + int arg2, + const QString &rArg3) const + { if (isEnabledFor(Level::ERROR_INT)) + forcedLog(Level::ERROR_INT, QString::fromUtf8(pMessage).arg(arg1).arg(arg2).arg(rArg3)); } + + inline void Logger::error(const char *pMessage, + int arg1, + int arg2, + int arg3) const + { if (isEnabledFor(Level::ERROR_INT)) + forcedLog(Level::ERROR_INT, QString::fromUtf8(pMessage).arg(arg1).arg(arg2).arg(arg3)); } + + inline void Logger::error(const char *pMessage, + const QVariant &rArg1, + const QVariant &rArg2, + const QVariant &rArg3) const + { if (isEnabledFor(Level::ERROR_INT)) + forcedLog(Level::ERROR_INT, QString::fromUtf8(pMessage).arg(rArg1.toString(), rArg2.toString(), rArg3.toString())); } + + // Log operations: fatal + + inline void Logger::fatal(const QString &rMessage) const + { if (isEnabledFor(Level::FATAL_INT)) + forcedLog(Level::FATAL_INT, rMessage); } + + inline void Logger::fatal(const LogError &rLogError) const + { if (isEnabledFor(Level::FATAL_INT)) + forcedLog(Level::FATAL_INT, rLogError.toString()); } + + inline void Logger::fatal(const char *pMessage) const + { if (isEnabledFor(Level::FATAL_INT)) + forcedLog(Level::FATAL_INT, QString::fromUtf8(pMessage)); } + + inline void Logger::fatal(const char *pMessage, + const QString &rArg1) const + { if (isEnabledFor(Level::FATAL_INT)) + forcedLog(Level::FATAL_INT, QString::fromUtf8(pMessage).arg(rArg1)); } + + inline void Logger::fatal(const char *pMessage, + int arg1) const + { if (isEnabledFor(Level::FATAL_INT)) + forcedLog(Level::FATAL_INT, QString::fromUtf8(pMessage).arg(arg1)); } + + inline void Logger::fatal(const char *pMessage, + const QString &rArg1, const QString &rArg2) const + { if (isEnabledFor(Level::FATAL_INT)) + forcedLog(Level::FATAL_INT, QString::fromUtf8(pMessage).arg(rArg1, rArg2)); } + + inline void Logger::fatal(const char *pMessage, + const QString &rArg1, int arg2) const + { if (isEnabledFor(Level::FATAL_INT)) + forcedLog(Level::FATAL_INT, QString::fromUtf8(pMessage).arg(rArg1).arg(arg2)); } + + inline void Logger::fatal(const char *pMessage, + int arg1, + const QString &rArg2) const + { if (isEnabledFor(Level::FATAL_INT)) + forcedLog(Level::FATAL_INT, QString::fromUtf8(pMessage).arg(arg1).arg(rArg2)); } + + inline void Logger::fatal(const char *pMessage, + int arg1, + int arg2) const + { if (isEnabledFor(Level::FATAL_INT)) + forcedLog(Level::FATAL_INT, QString::fromUtf8(pMessage).arg(arg1).arg(arg2)); } + + inline void Logger::fatal(const char *pMessage, + const QString &rArg1, + const QString &rArg2, + const QString &rArg3) const + { if (isEnabledFor(Level::FATAL_INT)) + forcedLog(Level::FATAL_INT, QString::fromUtf8(pMessage).arg(rArg1, rArg2, rArg3)); } + + inline void Logger::fatal(const char *pMessage, + const QString &rArg1, + const QString &rArg2, + int arg3) const + { if (isEnabledFor(Level::FATAL_INT)) + forcedLog(Level::FATAL_INT, QString::fromUtf8(pMessage).arg(rArg1, rArg2).arg(arg3)); } + + inline void Logger::fatal(const char *pMessage, + const QString &rArg1, + int arg2, + const QString &rArg3) const + { if (isEnabledFor(Level::FATAL_INT)) + forcedLog(Level::FATAL_INT, QString::fromUtf8(pMessage).arg(rArg1).arg(arg2).arg(rArg3)); } + + inline void Logger::fatal(const char *pMessage, + const QString &rArg1, + int arg2, + int arg3) const + { if (isEnabledFor(Level::FATAL_INT)) + forcedLog(Level::FATAL_INT, QString::fromUtf8(pMessage).arg(rArg1).arg(arg2).arg(arg3)); } + + inline void Logger::fatal(const char *pMessage, + int arg1, + const QString &rArg2, + const QString &rArg3) const + { if (isEnabledFor(Level::FATAL_INT)) + forcedLog(Level::FATAL_INT, QString::fromUtf8(pMessage).arg(arg1).arg(rArg2).arg(rArg3)); } + + inline void Logger::fatal(const char *pMessage, + int arg1, + const QString &rArg2, + int arg3) const + { if (isEnabledFor(Level::FATAL_INT)) + forcedLog(Level::FATAL_INT, QString::fromUtf8(pMessage).arg(arg1).arg(rArg2).arg(arg3)); } + + inline void Logger::fatal(const char *pMessage, + int arg1, + int arg2, + const QString &rArg3) const + { if (isEnabledFor(Level::FATAL_INT)) + forcedLog(Level::FATAL_INT, QString::fromUtf8(pMessage).arg(arg1).arg(arg2).arg(rArg3)); } + + inline void Logger::fatal(const char *pMessage, + int arg1, + int arg2, + int arg3) const + { if (isEnabledFor(Level::FATAL_INT)) + forcedLog(Level::FATAL_INT, QString::fromUtf8(pMessage).arg(arg1).arg(arg2).arg(arg3)); } + + inline void Logger::fatal(const char *pMessage, + const QVariant &rArg1, + const QVariant &rArg2, + const QVariant &rArg3) const + { if (isEnabledFor(Level::FATAL_INT)) + forcedLog(Level::FATAL_INT, QString::fromUtf8(pMessage).arg(rArg1.toString(), rArg2.toString(), rArg3.toString())); } + + // Log operations: info + + inline void Logger::info(const QString &rMessage) const + { if (isEnabledFor(Level::INFO_INT)) + forcedLog(Level::INFO_INT, rMessage); } + + inline void Logger::info(const LogError &rLogError) const + { if (isEnabledFor(Level::INFO_INT)) + forcedLog(Level::INFO_INT, rLogError.toString()); } + + inline void Logger::info(const char *pMessage) const + { if (isEnabledFor(Level::INFO_INT)) + forcedLog(Level::INFO_INT, QString::fromUtf8(pMessage)); } + + inline void Logger::info(const char *pMessage, + const QString &rArg1) const + { if (isEnabledFor(Level::INFO_INT)) + forcedLog(Level::INFO_INT, QString::fromUtf8(pMessage).arg(rArg1)); } + + inline void Logger::info(const char *pMessage, + int arg1) const + { if (isEnabledFor(Level::INFO_INT)) + forcedLog(Level::INFO_INT, QString::fromUtf8(pMessage).arg(arg1)); } + + inline void Logger::info(const char *pMessage, + const QString &rArg1, + const QString &rArg2) const + { if (isEnabledFor(Level::INFO_INT)) + forcedLog(Level::INFO_INT, QString::fromUtf8(pMessage).arg(rArg1, rArg2)); } + + inline void Logger::info(const char *pMessage, + const QString &rArg1, + int arg2) const + { if (isEnabledFor(Level::INFO_INT)) + forcedLog(Level::INFO_INT, QString::fromUtf8(pMessage).arg(rArg1).arg(arg2)); } + + inline void Logger::info(const char *pMessage, + int arg1, + const QString &rArg2) const + { if (isEnabledFor(Level::INFO_INT)) + forcedLog(Level::INFO_INT, QString::fromUtf8(pMessage).arg(arg1).arg(rArg2)); } + + inline void Logger::info(const char *pMessage, + int arg1, + int arg2) const + { if (isEnabledFor(Level::INFO_INT)) + forcedLog(Level::INFO_INT, QString::fromUtf8(pMessage).arg(arg1).arg(arg2)); } + + inline void Logger::info(const char *pMessage, + const QString &rArg1, + const QString &rArg2, + const QString &rArg3) const + { if (isEnabledFor(Level::INFO_INT)) + forcedLog(Level::INFO_INT, QString::fromUtf8(pMessage).arg(rArg1, rArg2, rArg3)); } + + inline void Logger::info(const char *pMessage, + const QString &rArg1, + const QString &rArg2, + int arg3) const + { if (isEnabledFor(Level::INFO_INT)) + forcedLog(Level::INFO_INT, QString::fromUtf8(pMessage).arg(rArg1, rArg2).arg(arg3)); } + + inline void Logger::info(const char *pMessage, + const QString &rArg1, + int arg2, + const QString &rArg3) const + { if (isEnabledFor(Level::INFO_INT)) + forcedLog(Level::INFO_INT, QString::fromUtf8(pMessage).arg(rArg1).arg(arg2).arg(rArg3)); } + + inline void Logger::info(const char *pMessage, + const QString &rArg1, + int arg2, + int arg3) const + { if (isEnabledFor(Level::INFO_INT)) + forcedLog(Level::INFO_INT, QString::fromUtf8(pMessage).arg(rArg1).arg(arg2).arg(arg3)); } + + inline void Logger::info(const char *pMessage, + int arg1, + const QString &rArg2, + const QString &rArg3) const + { if (isEnabledFor(Level::INFO_INT)) + forcedLog(Level::INFO_INT, QString::fromUtf8(pMessage).arg(arg1).arg(rArg2).arg(rArg3)); } + + inline void Logger::info(const char *pMessage, + int arg1, + const QString &rArg2, + int arg3) const + { if (isEnabledFor(Level::INFO_INT)) + forcedLog(Level::INFO_INT, QString::fromUtf8(pMessage).arg(arg1).arg(rArg2).arg(arg3)); } + + inline void Logger::info(const char *pMessage, + int arg1, + int arg2, + const QString &rArg3) const + { if (isEnabledFor(Level::INFO_INT)) + forcedLog(Level::INFO_INT, QString::fromUtf8(pMessage).arg(arg1).arg(arg2).arg(rArg3)); } + + inline void Logger::info(const char *pMessage, + int arg1, + int arg2, + int arg3) const + { if (isEnabledFor(Level::INFO_INT)) + forcedLog(Level::INFO_INT, QString::fromUtf8(pMessage).arg(arg1).arg(arg2).arg(arg3)); } + + inline void Logger::info(const char *pMessage, + const QVariant &rArg1, + const QVariant &rArg2, + const QVariant &rArg3) const + { if (isEnabledFor(Level::INFO_INT)) + forcedLog(Level::INFO_INT, QString::fromUtf8(pMessage).arg(rArg1.toString(), rArg2.toString(), rArg3.toString())); } + + // Log operations: log + + inline void Logger::log(Level level, + const QString &rMessage) const + { if (isEnabledFor(level)) + forcedLog(level, rMessage); } + + inline void Logger::log(Level level, + const LogError &rLogError) const + { if (isEnabledFor(level)) + forcedLog(level, rLogError.toString()); } + + inline void Logger::log(Level level, + const char *pMessage) const + { if (isEnabledFor(level)) + forcedLog(level, QString::fromUtf8(pMessage)); } + + inline void Logger::log(Level level, + const char *pMessage, + const QString &rArg1) const + { if (isEnabledFor(level)) + forcedLog(level, QString::fromUtf8(pMessage).arg(rArg1)); } + + inline void Logger::log(Level level, + const char *pMessage, + int arg1) const + { if (isEnabledFor(level)) + forcedLog(level, QString::fromUtf8(pMessage).arg(arg1)); } + + inline void Logger::log(Level level, + const char *pMessage, + const QString &rArg1, + const QString &rArg2) const + { if (isEnabledFor(level)) + forcedLog(level, QString::fromUtf8(pMessage).arg(rArg1, rArg2)); } + + inline void Logger::log(Level level, + const char *pMessage, + const QString &rArg1, int arg2) const + { if (isEnabledFor(level)) + forcedLog(level, QString::fromUtf8(pMessage).arg(rArg1).arg(arg2)); } + + inline void Logger::log(Level level, + const char *pMessage, + int arg1, + const QString &rArg2) const + { if (isEnabledFor(level)) + forcedLog(level, QString::fromUtf8(pMessage).arg(arg1).arg(rArg2)); } + + inline void Logger::log(Level level, + const char *pMessage, + int arg1, + int arg2) const + { if (isEnabledFor(level)) + forcedLog(level, QString::fromUtf8(pMessage).arg(arg1).arg(arg2)); } + + inline void Logger::log(Level level, + const char *pMessage, + const QString &rArg1, + const QString &rArg2, + const QString &rArg3) const + { if (isEnabledFor(level)) + forcedLog(level, QString::fromUtf8(pMessage).arg(rArg1, rArg2, rArg3)); } + + inline void Logger::log(Level level, + const char *pMessage, + const QString &rArg1, + const QString &rArg2, + int arg3) const + { if (isEnabledFor(level)) + forcedLog(level, QString::fromUtf8(pMessage).arg(rArg1, rArg2).arg(arg3)); } + + inline void Logger::log(Level level, + const char *pMessage, + const QString &rArg1, + int arg2, + const QString &rArg3) const + { if (isEnabledFor(level)) + forcedLog(level, QString::fromUtf8(pMessage).arg(rArg1).arg(arg2).arg(rArg3)); } + + inline void Logger::log(Level level, + const char *pMessage, + const QString &rArg1, + int arg2, + int arg3) const + { if (isEnabledFor(level)) + forcedLog(level, QString::fromUtf8(pMessage).arg(rArg1).arg(arg2).arg(arg3)); } + + inline void Logger::log(Level level, + const char *pMessage, + int arg1, + const QString &rArg2, + const QString &rArg3) const + { if (isEnabledFor(level)) + forcedLog(level, QString::fromUtf8(pMessage).arg(arg1).arg(rArg2).arg(rArg3)); } + + inline void Logger::log(Level level, + const char *pMessage, + int arg1, + const QString &rArg2, + int arg3) const + { if (isEnabledFor(level)) + forcedLog(level, QString::fromUtf8(pMessage).arg(arg1).arg(rArg2).arg(arg3)); } + + inline void Logger::log(Level level, + const char *pMessage, + int arg1, + int arg2, + const QString &rArg3) const + { if (isEnabledFor(level)) + forcedLog(level, QString::fromUtf8(pMessage).arg(arg1).arg(arg2).arg(rArg3)); } + + inline void Logger::log(Level level, + const char *pMessage, + int arg1, + int arg2, + int arg3) const + { if (isEnabledFor(level)) + forcedLog(level, QString::fromUtf8(pMessage).arg(arg1).arg(arg2).arg(arg3)); } + + inline void Logger::log(Level level, + const char *pMessage, + const QVariant &rArg1, + const QVariant &rArg2, + const QVariant &rArg3) const + { if (isEnabledFor(level)) + forcedLog(level, QString::fromUtf8(pMessage).arg(rArg1.toString(), rArg2.toString(), rArg3.toString())); } + + // Log operations: trace + + inline void Logger::trace(const QString &rMessage) const + { if (isEnabledFor(Level::TRACE_INT)) + forcedLog(Level::TRACE_INT, rMessage); } + + inline void Logger::trace(const LogError &rLogError) const + { if (isEnabledFor(Level::TRACE_INT)) + forcedLog(Level::TRACE_INT, rLogError.toString()); } + + inline void Logger::trace(const char *pMessage) const + { if (isEnabledFor(Level::TRACE_INT)) + forcedLog(Level::TRACE_INT, QString::fromUtf8(pMessage)); } + + inline void Logger::trace(const char *pMessage, + const QString &rArg1) const + { if (isEnabledFor(Level::TRACE_INT)) + forcedLog(Level::TRACE_INT, QString::fromUtf8(pMessage).arg(rArg1)); } + + inline void Logger::trace(const char *pMessage, + int arg1) const + { if (isEnabledFor(Level::TRACE_INT)) + forcedLog(Level::TRACE_INT, QString::fromUtf8(pMessage).arg(arg1)); } + + inline void Logger::trace(const char *pMessage, + const QString &rArg1, + const QString &rArg2) const + { if (isEnabledFor(Level::TRACE_INT)) + forcedLog(Level::TRACE_INT, QString::fromUtf8(pMessage).arg(rArg1, rArg2)); } + + inline void Logger::trace(const char *pMessage, + const QString &rArg1, + int arg2) const + { if (isEnabledFor(Level::TRACE_INT)) + forcedLog(Level::TRACE_INT, QString::fromUtf8(pMessage).arg(rArg1).arg(arg2)); } + + inline void Logger::trace(const char *pMessage, + int arg1, + const QString &rArg2) const + { if (isEnabledFor(Level::TRACE_INT)) + forcedLog(Level::TRACE_INT, QString::fromUtf8(pMessage).arg(arg1).arg(rArg2)); } + + inline void Logger::trace(const char *pMessage, + int arg1, + int arg2) const + { if (isEnabledFor(Level::TRACE_INT)) + forcedLog(Level::TRACE_INT, QString::fromUtf8(pMessage).arg(arg1).arg(arg2)); } + + inline void Logger::trace(const char *pMessage, + const QString &rArg1, + const QString &rArg2, + const QString &rArg3) const + { if (isEnabledFor(Level::TRACE_INT)) + forcedLog(Level::TRACE_INT, QString::fromUtf8(pMessage).arg(rArg1, rArg2, rArg3)); } + + inline void Logger::trace(const char *pMessage, + const QString &rArg1, + const QString &rArg2, + int arg3) const + { if (isEnabledFor(Level::TRACE_INT)) + forcedLog(Level::TRACE_INT, QString::fromUtf8(pMessage).arg(rArg1, rArg2).arg(arg3)); } + + inline void Logger::trace(const char *pMessage, + const QString &rArg1, + int arg2, + const QString &rArg3) const + { if (isEnabledFor(Level::TRACE_INT)) + forcedLog(Level::TRACE_INT, QString::fromUtf8(pMessage).arg(rArg1).arg(arg2).arg(rArg3)); } + + inline void Logger::trace(const char *pMessage, + const QString &rArg1, + int arg2, + int arg3) const + { if (isEnabledFor(Level::TRACE_INT)) + forcedLog(Level::TRACE_INT, QString::fromUtf8(pMessage).arg(rArg1).arg(arg2).arg(arg3)); } + + inline void Logger::trace(const char *pMessage, + int arg1, + const QString &rArg2, + const QString &rArg3) const + { if (isEnabledFor(Level::TRACE_INT)) + forcedLog(Level::TRACE_INT, QString::fromUtf8(pMessage).arg(arg1).arg(rArg2).arg(rArg3)); } + + inline void Logger::trace(const char *pMessage, + int arg1, + const QString &rArg2, + int arg3) const + { if (isEnabledFor(Level::TRACE_INT)) + forcedLog(Level::TRACE_INT, QString::fromUtf8(pMessage).arg(arg1).arg(rArg2).arg(arg3)); } + + inline void Logger::trace(const char *pMessage, + int arg1, + int arg2, + const QString &rArg3) const + { if (isEnabledFor(Level::TRACE_INT)) + forcedLog(Level::TRACE_INT, QString::fromUtf8(pMessage).arg(arg1).arg(arg2).arg(rArg3)); } + + inline void Logger::trace(const char *pMessage, + int arg1, + int arg2, + int arg3) const + { if (isEnabledFor(Level::TRACE_INT)) + forcedLog(Level::TRACE_INT, QString::fromUtf8(pMessage).arg(arg1).arg(arg2).arg(arg3)); } + + inline void Logger::trace(const char *pMessage, + const QVariant &rArg1, + const QVariant &rArg2, + const QVariant &rArg3) const + { if (isEnabledFor(Level::TRACE_INT)) + forcedLog(Level::TRACE_INT, QString::fromUtf8(pMessage).arg(rArg1.toString(), rArg2.toString(), rArg3.toString())); } + + // Log operations: warn + + inline void Logger::warn(const QString &rMessage) const + { if (isEnabledFor(Level::WARN_INT)) + forcedLog(Level::WARN_INT, rMessage); } + + inline void Logger::warn(const LogError &rLogError) const + { if (isEnabledFor(Level::WARN_INT)) + forcedLog(Level::WARN_INT, rLogError.toString()); } + + inline void Logger::warn(const char *pMessage) const + { if (isEnabledFor(Level::WARN_INT)) + forcedLog(Level::WARN_INT, QString::fromUtf8(pMessage)); } + + inline void Logger::warn(const char *pMessage, + const QString &rArg1) const + { if (isEnabledFor(Level::WARN_INT)) + forcedLog(Level::WARN_INT, QString::fromUtf8(pMessage).arg(rArg1)); } + + inline void Logger::warn(const char *pMessage, + int arg1) const + { if (isEnabledFor(Level::WARN_INT)) + forcedLog(Level::WARN_INT, QString::fromUtf8(pMessage).arg(arg1)); } + + inline void Logger::warn(const char *pMessage, + const QString &rArg1, + const QString &rArg2) const + { if (isEnabledFor(Level::WARN_INT)) + forcedLog(Level::WARN_INT, QString::fromUtf8(pMessage).arg(rArg1, rArg2)); } + + inline void Logger::warn(const char *pMessage, + const QString &rArg1, + int arg2) const + { if (isEnabledFor(Level::WARN_INT)) + forcedLog(Level::WARN_INT, QString::fromUtf8(pMessage).arg(rArg1).arg(arg2)); } + + inline void Logger::warn(const char *pMessage, + int arg1, + const QString &rArg2) const + { if (isEnabledFor(Level::WARN_INT)) + forcedLog(Level::WARN_INT, QString::fromUtf8(pMessage).arg(arg1).arg(rArg2)); } + + inline void Logger::warn(const char *pMessage, + int arg1, + int arg2) const + { if (isEnabledFor(Level::WARN_INT)) + forcedLog(Level::WARN_INT, QString::fromUtf8(pMessage).arg(arg1).arg(arg2)); } + + inline void Logger::warn(const char *pMessage, + const QString &rArg1, + const QString &rArg2, + const QString &rArg3) const + { if (isEnabledFor(Level::WARN_INT)) + forcedLog(Level::WARN_INT, QString::fromUtf8(pMessage).arg(rArg1, rArg2, rArg3)); } + + inline void Logger::warn(const char *pMessage, + const QString &rArg1, + const QString &rArg2, + int arg3) const + { if (isEnabledFor(Level::WARN_INT)) + forcedLog(Level::WARN_INT, QString::fromUtf8(pMessage).arg(rArg1, rArg2).arg(arg3)); } + + inline void Logger::warn(const char *pMessage, + const QString &rArg1, + int arg2, + const QString &rArg3) const + { if (isEnabledFor(Level::WARN_INT)) + forcedLog(Level::WARN_INT, QString::fromUtf8(pMessage).arg(rArg1).arg(arg2).arg(rArg3)); } + + inline void Logger::warn(const char *pMessage, + const QString &rArg1, + int arg2, + int arg3) const + { if (isEnabledFor(Level::WARN_INT)) + forcedLog(Level::WARN_INT, QString::fromUtf8(pMessage).arg(rArg1).arg(arg2).arg(arg3)); } + + inline void Logger::warn(const char *pMessage, + int arg1, + const QString &rArg2, + const QString &rArg3) const + { if (isEnabledFor(Level::WARN_INT)) + forcedLog(Level::WARN_INT, QString::fromUtf8(pMessage).arg(arg1).arg(rArg2).arg(rArg3)); } + + inline void Logger::warn(const char *pMessage, + int arg1, + const QString &rArg2, + int arg3) const + { if (isEnabledFor(Level::WARN_INT)) + forcedLog(Level::WARN_INT, QString::fromUtf8(pMessage).arg(arg1).arg(rArg2).arg(arg3)); } + + inline void Logger::warn(const char *pMessage, + int arg1, + int arg2, + const QString &rArg3) const + { if (isEnabledFor(Level::WARN_INT)) + forcedLog(Level::WARN_INT, QString::fromUtf8(pMessage).arg(arg1).arg(arg2).arg(rArg3)); } + + inline void Logger::warn(const char *pMessage, + int arg1, + int arg2, + int arg3) const + { if (isEnabledFor(Level::WARN_INT)) + forcedLog(Level::WARN_INT, QString::fromUtf8(pMessage).arg(arg1).arg(arg2).arg(arg3)); } + + inline void Logger::warn(const char *pMessage, + const QVariant &rArg1, + const QVariant &rArg2, + const QVariant &rArg3) const + { if (isEnabledFor(Level::WARN_INT)) + forcedLog(Level::WARN_INT, QString::fromUtf8(pMessage).arg(rArg1.toString(), rArg2.toString(), rArg3.toString())); } + + +} // namespace Log4Qt + + +// Q_DECLARE_TYPEinfo(Log4Qt::Logger, Q_COMPLEX_TYPE); // Use default + + +#endif // LOG4QT_LOGGER_H diff --git a/src/log4qt/log4qt/loggerrepository.cpp b/src/log4qt/log4qt/loggerrepository.cpp new file mode 100644 index 0000000..b541bb2 --- /dev/null +++ b/src/log4qt/log4qt/loggerrepository.cpp @@ -0,0 +1,75 @@ +/****************************************************************************** + * + * package: Log4Qt + * file: loggerrepository.cpp + * created: September 2007 + * author: Martin Heinrich + * + * + * Copyright 2007 Martin Heinrich + * + * 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. + * + ******************************************************************************/ + + + +/****************************************************************************** + * Dependencies + ******************************************************************************/ + + +#include "log4qt/loggerrepository.h" + +#include + + + +namespace Log4Qt +{ + + + /************************************************************************** + * Declarations + **************************************************************************/ + + + + /************************************************************************** + * C helper functions + **************************************************************************/ + + + + /************************************************************************** + * Class implementation: LoggerRepository + **************************************************************************/ + + + + /************************************************************************** + * Implementation: Operators, Helper + **************************************************************************/ + + +#ifndef QT_NO_DEBUG_STREAM + QDebug operator<<(QDebug debug, + const LoggerRepository &rLoggerRepository) + { + return rLoggerRepository.debug(debug); + } +#endif // QT_NO_DEBUG_STREAM + + + +} // namespace Log4Qt diff --git a/src/log4qt/log4qt/loggerrepository.h b/src/log4qt/log4qt/loggerrepository.h new file mode 100644 index 0000000..fdf5b5c --- /dev/null +++ b/src/log4qt/log4qt/loggerrepository.h @@ -0,0 +1,129 @@ +/****************************************************************************** + * + * package: Log4Qt + * file: loggerrepository.h + * created: September 2007 + * author: Martin Heinrich + * + * + * Copyright 2007 Martin Heinrich + * + * 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. + * + ******************************************************************************/ + +#ifndef LOG4QT_LOGGERREPOSITORY_H +#define LOG4QT_LOGGERREPOSITORY_H + + +/****************************************************************************** + * Dependencies + ******************************************************************************/ + +#include +#include "log4qt/level.h" +#include "ukui-logmacros.h" + + +/****************************************************************************** + * Declarations + ******************************************************************************/ + +namespace Log4Qt +{ + + class Logger; + + /*! + * \brief The class LoggerRepository is abstract base class for a logger + * repository. + */ + class LIBUKUILOG4QT_EXPORT LoggerRepository + { + public: + // LoggerRepository(); // Use compiler default + // LoggerRepository(const LoggerRepository &rOther); // Use compiler default + // virtual ~LoggerRepository(); // Use compiler default + // LoggerRepository &operator=(const LoggerRepository &rOther); // Use compiler default + + public: + virtual bool exists(const QString &rName) const = 0; + virtual Logger *logger(const QString &rName) = 0; + // JAVA: virtual Logger *logger(const String &rName, LoggerFactory *pFactory); + virtual QList loggers() const = 0; + virtual Logger *rootLogger() const = 0; + virtual Level threshold() const = 0; + virtual void setThreshold(Level level) = 0; + virtual void setThreshold(const QString &rThreshold) = 0; + + virtual bool isDisabled(Level level) = 0; + virtual void resetConfiguration() = 0; + virtual void shutdown() = 0; + + // JAVA: virtual void addHierarchyEventListener(HierarchyEventListener *pEventListener); + // JAVA: virtual void emitNoAppenderWarning(Logger *plogger) const; + // JAVA: virtual void fireAddAppenderEvent(Logger *plogger, Appender *pAppender) const; + + protected: +#ifndef QT_NO_DEBUG_STREAM + /*! + *\relates LoggerRepository + * + * Writes all object member variables to the given debug stream \a rDebug + * and returns the stream. + * + * The member function is used by + * QDebug operator<<(QDebug debug, const LoggerRepository &rLoggerRepository) + * to generate class specific output. + * + * \sa QDebug operator<<(QDebug debug, const LoggerRepository &rLoggerRepository) + */ + virtual QDebug debug(QDebug &rDebug) const = 0; + friend QDebug operator<<(QDebug debug, + const LoggerRepository &rLoggerRepository); +#endif + }; + + + /****************************************************************************** + * Operators, Helper + ******************************************************************************/ + +#ifndef QT_NO_DEBUG_STREAM + /*! + * \relates LoggerRepository + * Writes all object member variables to the given debug stream \a debug + * and returns the stream. + * + * To handle subclassing the function uses the virtual member function + * debug(). This allows each class to generate its own output. + * + * \sa QDebug, debug() + */ + QDebug operator<<(QDebug debug, + const LoggerRepository &rLoggerRepository); +#endif + + + /************************************************************************** + * Inline + **************************************************************************/ + + +} // namespace Log4Qt + + +// Q_DECLARE_TYPEINFO(Log4Qt::LoggerRepository, Q_COMPLEX_TYPE); // Use default + + +#endif // LOG4QT_LOGGERREPOSITORY_H diff --git a/src/log4qt/log4qt/loggingevent.cpp b/src/log4qt/log4qt/loggingevent.cpp new file mode 100644 index 0000000..7570d20 --- /dev/null +++ b/src/log4qt/log4qt/loggingevent.cpp @@ -0,0 +1,276 @@ +/****************************************************************************** + * + * package: Log4Qt + * file: loggingevent.cpp + * created: September 2007 + * author: Martin Heinrich + * + * + * Copyright 2007 Martin Heinrich + * + * 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. + * + *****************************************************************************/ + + + +/****************************************************************************** + * Dependencies + ******************************************************************************/ + + +#include "log4qt/loggingevent.h" + +#include +#include +#include +#include +#include +#include +#include "log4qt/helpers/datetime.h" +#include "log4qt/helpers/initialisationhelper.h" +#include "log4qt/logger.h" +#include "log4qt/mdc.h" +#include "log4qt/ndc.h" + + + +namespace Log4Qt +{ + + + /************************************************************************** + * Declarations + **************************************************************************/ + + + LOG4QT_GLOBAL_STATIC(QMutex, sequence_guard) + + + + /************************************************************************** + * C helper functions + **************************************************************************/ + + + + /************************************************************************** + * Class implementation: LoggingEvent + **************************************************************************/ + + + LoggingEvent::LoggingEvent() : + mLevel(Level::NULL_INT), + mpLogger(0), + mMessage(), + mNdc(NDC::peek()), + mProperties(MDC::context()), + mSequenceNumber(nextSequenceNumber()), + mThreadName(), + mTimeStamp(DateTime::currentDateTime().toMilliSeconds()) + { + setThreadNameToCurrent(); + } + + + LoggingEvent::LoggingEvent(const Logger *pLogger, + Level level, + const QString &rMessage) : + mLevel(level), + mpLogger(pLogger), + mMessage(rMessage), + mNdc(NDC::peek()), + mProperties(MDC::context()), + mSequenceNumber(nextSequenceNumber()), + mThreadName(), + mTimeStamp(DateTime::currentDateTime().toMilliSeconds()) + { + setThreadNameToCurrent(); + } + + + LoggingEvent::LoggingEvent(const Logger *pLogger, + Level level, + const QString &rMessage, + qint64 timeStamp) : + mLevel(level), + mpLogger(pLogger), + mMessage(rMessage), + mNdc(NDC::peek()), + mProperties(MDC::context()), + mSequenceNumber(nextSequenceNumber()), + mThreadName(), + mTimeStamp(timeStamp) + { + setThreadNameToCurrent(); + } + + + LoggingEvent::LoggingEvent(const Logger *pLogger, + Level level, + const QString &rMessage, + const QString &rNdc, + const QHash &rProperties, + const QString &rThreadName, + qint64 timeStamp) : + mLevel(level), + mpLogger(pLogger), + mMessage(rMessage), + mNdc(rNdc), + mProperties(rProperties), + mSequenceNumber(nextSequenceNumber()), + mThreadName(rThreadName), + mTimeStamp(timeStamp) + { + } + + + QString LoggingEvent::loggerName() const + { + if (mpLogger) + return mpLogger->name(); + else + return QString(); + } + + + QString LoggingEvent::toString() const + { + return level().toString() + QLatin1Char(':') + message(); + } + + + qint64 LoggingEvent::sequenceCount() + { + QMutexLocker locker(sequence_guard()); + + return msSequenceCount; + } + + + qint64 LoggingEvent::startTime() + { + return InitialisationHelper::startTime(); + } + + + void LoggingEvent::setThreadNameToCurrent() + { + if (QThread::currentThread()) { + mThreadName = QThread::currentThread()->objectName(); + if (mThreadName.isEmpty()) { + mThreadName = QString("%1").arg((quint64)QThread::currentThreadId()); + } + } + } + + + qint64 LoggingEvent::nextSequenceNumber() + { + QMutexLocker locker(sequence_guard()); + + return ++msSequenceCount; + } + + + qint64 LoggingEvent::msSequenceCount = 0; + + + + /************************************************************************** + * Implementation: Operators, Helper + **************************************************************************/ + + +#ifndef QT_NO_DATASTREAM + QDataStream &operator<<(QDataStream &rStream, const LoggingEvent &rLoggingEvent) + { + QBuffer buffer; + buffer.open(QIODevice::WriteOnly); + QDataStream stream(&buffer); + + // version + quint16 version = 0; + stream << version; + // version 0 data + stream << rLoggingEvent.mLevel + << rLoggingEvent.loggerName() + << rLoggingEvent.mMessage + << rLoggingEvent.mNdc + << rLoggingEvent.mProperties + << rLoggingEvent.mSequenceNumber + << rLoggingEvent.mThreadName + << rLoggingEvent.mTimeStamp; + + buffer.close(); + rStream << buffer.buffer(); + return rStream; + } + + + QDataStream &operator>>(QDataStream &rStream, LoggingEvent &rLoggingEvent) + { + QByteArray array; + rStream >> array; + QBuffer buffer(&array); + buffer.open(QIODevice::ReadOnly); + QDataStream stream(&buffer); + + // version + quint16 version; + stream >> version; + // Version 0 data + QString logger; + stream >> rLoggingEvent.mLevel + >> logger + >> rLoggingEvent.mMessage + >> rLoggingEvent.mNdc + >> rLoggingEvent.mProperties + >> rLoggingEvent.mSequenceNumber + >> rLoggingEvent.mThreadName + >> rLoggingEvent.mTimeStamp; + if (logger.isEmpty()) + rLoggingEvent.mpLogger = 0; + else + rLoggingEvent.mpLogger = Logger::logger(logger); + + buffer.close(); + return rStream; + } +#endif // QT_NO_DATASTREAM + + +#ifndef QT_NO_DEBUG_STREAM + QDebug operator<<(QDebug debug, + const LoggingEvent &rLoggingEvent) + { + QString logger; + if (rLoggingEvent.logger() != 0) + logger = rLoggingEvent.logger()->name(); + + debug.nospace() << "LoggingEvent(" + << "level:" << rLoggingEvent.level().toString() << " " + << "logger:" << logger << " " + << "message:" << rLoggingEvent.message() << " " + << "sequencenumber:" << rLoggingEvent.sequenceNumber() << " " + << "threadname:" << rLoggingEvent.threadName() << " " + << "timestamp:" << rLoggingEvent.timeStamp() + << "(" << DateTime::fromMilliSeconds(rLoggingEvent.timeStamp()) << ")" + << "sequenceCount:" << rLoggingEvent.sequenceCount() + << ")"; + return debug.space(); + } +#endif // QT_NO_DEBUG_STREAM + + +} // namespace Log4Qt diff --git a/src/log4qt/log4qt/loggingevent.h b/src/log4qt/log4qt/loggingevent.h new file mode 100644 index 0000000..7b9568a --- /dev/null +++ b/src/log4qt/log4qt/loggingevent.h @@ -0,0 +1,222 @@ +/****************************************************************************** +* +* package: Log4Qt +* file: loggingevent.h +* created: September 2007 +* author: Martin Heinrich + * + * + * Copyright 2007 Martin Heinrich + * + * 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. + * +******************************************************************************/ + +#ifndef LOG4QT_LOG4QTEVENT_H +#define LOG4QT_LOG4QTEVENT_H + + +/****************************************************************************** + * Dependencies + ******************************************************************************/ + +#include +#include +#include +#include +#include "log4qt/level.h" +#include "ukui-logmacros.h" + + +/****************************************************************************** + * Declarations + ******************************************************************************/ + +namespace Log4Qt +{ + + class Logger; + + /*! + * \brief The class LoggingEvent is the internal representation of a + * logging event. + * + * The class uses milliseconds since 1970-01-01T00:00:00, Coordinated + * Universal Time for time values. For converstion from and to QDateTime + * use DateTime. + */ + class LIBUKUILOG4QT_EXPORT LoggingEvent + { + public: + LoggingEvent(); + LoggingEvent(const Logger *pLogger, + Level level, + const QString &rMessage); + LoggingEvent(const Logger *pLogger, + Level level, + const QString &rMessage, + qint64 timeStamp); + LoggingEvent(const Logger *pLogger, + Level level, + const QString &rMessage, + const QString &rNdc, + const QHash &rProperties, + const QString &rThreadName, + qint64 timeStamp); + // LoggingEvent(const LoggingEvent &LoggingEvent::rOther); // Use compiler default + // virtual ~LoggingEvent(); // Use compiler default + // LoggingEvent &operator=(const LoggingEvent &LoggingEvent::rOther); // Use compiler default + + // JAVA: QString fqnOfLoggerClass() const; + Level level() const; + // LocationInformation locationInformation() const; + const Logger *logger() const; + QString message() const; + QHash mdc() const; + QString ndc() const; + QHash properties() const; + qint64 sequenceNumber() const; + QString threadName() const; + // JAVA: ThrowableInformation throwableInformation() const; + qint64 timeStamp() const; + + // JAVA: bool locationInformationExists() const; + QString loggerName() const; + QString property(const QString &rKey) const; + QStringList propertyKeys() const; + void setProperty(const QString &rKey, const QString &rValue); + // JAVA: QString throwableStrRep() const; + QString toString() const; + static qint64 sequenceCount(); + static qint64 startTime(); + + private: + void setThreadNameToCurrent(); + static qint64 nextSequenceNumber(); + + private: + Level mLevel; + const Logger *mpLogger; + QString mMessage; + QString mNdc; + QHash mProperties; + qint64 mSequenceNumber; + QString mThreadName; + qint64 mTimeStamp; + static qint64 msSequenceCount; + +#ifndef QT_NO_DATASTREAM + // Needs to be friend to stream objects + friend QDataStream &operator<<(QDataStream &rStream, + const LoggingEvent &rLoggingEvent); + friend QDataStream &operator>>(QDataStream &rStream, + LoggingEvent &rLoggingEvent); +#endif // QT_NO_DATASTREAM + }; + + + /************************************************************************** + * Operators, Helper + **************************************************************************/ + +#ifndef QT_NO_DATASTREAM + /*! + * \relates LoggingEvent + * + * Writes the given error \a rLoggingEvent to the given stream \a rStream, + * and returns a reference to the stream. + */ + QDataStream &operator<<(QDataStream &rStream, + const LoggingEvent &rLoggingEvent); + + /*! + * \relates LoggingEvent + * + * Reads an error from the given stream \a rStream into the given + * error \a rLoggingEvent, and returns a reference to the stream. + */ + QDataStream &operator>>(QDataStream &rStream, + LoggingEvent &rLoggingEvent); +#endif // QT_NO_DATASTREAM + +#ifndef QT_NO_DEBUG_STREAM + /*! + * \relates LoggingEvent + * + * Writes all object member variables to the given debug stream \a debug and + * returns the stream. + * + * + * %LoggingEvent(level:"WARN" logger:"Log4Qt::Properties" + * message:"Unknown escape sequence '\j' in property starting at line 1" + * sequencenumber:14 threadname:"main" + * timestamp:1194337148937(QDateTime("Tue Nov 6 03:19:08 2007") ) + * sequenceCount: 14 ) + * + * + * \sa QDebug + */ + QDebug operator<<(QDebug debug, + const LoggingEvent &rLoggingEvent); +#endif // QT_NO_DEBUG_STREAM + + + /************************************************************************** + * Inline + **************************************************************************/ + + inline Level LoggingEvent::level() const + { return mLevel; } + + inline const Logger *LoggingEvent::logger() const + { return mpLogger; } + + inline QString LoggingEvent::message() const + { return mMessage; } + + inline QHash LoggingEvent::mdc() const + { return mProperties; } + + inline QString LoggingEvent::ndc() const + { return mNdc; } + + inline QHash LoggingEvent::properties() const + { return mProperties; } + + inline qint64 LoggingEvent::sequenceNumber() const + { return mSequenceNumber; } + + inline QString LoggingEvent::threadName() const + { return mThreadName; } + + inline qint64 LoggingEvent::timeStamp() const + { return mTimeStamp; } + + inline QString LoggingEvent::property(const QString &rKey) const + { return mProperties.value(rKey); } + + inline QStringList LoggingEvent::propertyKeys() const + { return QStringList(mProperties.keys()); } + + inline void LoggingEvent::setProperty(const QString &rKey, const QString &rValue) + { mProperties.insert(rKey, rValue); } + + +} // namespace Log4Qt + + +Q_DECLARE_METATYPE(Log4Qt::LoggingEvent) +Q_DECLARE_TYPEINFO(Log4Qt::LoggingEvent, Q_MOVABLE_TYPE); + + +#endif // LOG4QT_LOG4QTEVENT_H diff --git a/src/log4qt/log4qt/logmanager.cpp b/src/log4qt/log4qt/logmanager.cpp new file mode 100644 index 0000000..992ece5 --- /dev/null +++ b/src/log4qt/log4qt/logmanager.cpp @@ -0,0 +1,510 @@ +/****************************************************************************** + * + * package: Log4Qt + * file: logmanager.cpp + * created: September 2007 + * author: Martin Heinrich + * + * + * changes: Sep 2008, Martin Heinrich: + * - Resolved compilation problem with Microsoft Visual Studio 2005 + * Feb 2009, Martin Heinrich + * - Fixed VS 2008 unreferenced formal parameter warning by using + * Q_UNUSED in operator<<. + * + * + * Copyright 2007 - 2009 Martin Heinrich + * + * 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. + * + ******************************************************************************/ + + + +/****************************************************************************** + * Dependencies + ******************************************************************************/ + + +#include "log4qt/logmanager.h" + +#include +#include +#include +#include +#include +#include +#include "log4qt/consoleappender.h" +#include "log4qt/helpers/datetime.h" +#include "log4qt/helpers/initialisationhelper.h" +#include "log4qt/helpers/optionconverter.h" +#include "log4qt/hierarchy.h" +#include "log4qt/propertyconfigurator.h" +#include "log4qt/ttcclayout.h" +#include "log4qt/varia/denyallfilter.h" +#include "log4qt/varia/levelrangefilter.h" + + +namespace Log4Qt +{ + + + /************************************************************************** + * Declarations + **************************************************************************/ + + + + /************************************************************************** + * C helper functions + **************************************************************************/ + + + LOG4QT_DECLARE_STATIC_LOGGER(static_logger, Log4Qt::LogManager) + LOG4QT_GLOBAL_STATIC(QMutex, singleton_guard) + + + + /************************************************************************** + * Class implementation: LogManager + **************************************************************************/ + + + LogManager::LogManager() : + mObjectGuard(QMutex::Recursive), // Recursive for doStartup() to call doConfigureLogLogger() + mpLoggerRepository(new Hierarchy()), + mHandleQtMessages(false), + mOldQtMsgHandler(0) + { + } + + + LogManager::~LogManager() + { + static_logger()->warn("Unexpected destruction of LogManager"); + + // doSetConfigureHandleQtMessages(false); + // delete mpLoggerRepository; + } + + + Logger *LogManager::rootLogger() + { + return instance()->mpLoggerRepository->rootLogger(); + } + + + QList LogManager::loggers() + { + return instance()->mpLoggerRepository->loggers(); + } + + + Level LogManager::threshold() + { + return instance()->mpLoggerRepository->threshold(); + } + + + void LogManager::setThreshold(Level level) + { + instance()->mpLoggerRepository->setThreshold(level); + } + + + bool LogManager::exists(const char *pName) + { + return instance()->mpLoggerRepository->exists(QLatin1String(pName)); + } + + + LogManager *LogManager::instance() + { + // Do not use LOG4QT_GLOBAL_STATIC. The LogManager is rather expensive + // to construct, an exit handler must be set and doStartup must be + // called. + + if (!mspInstance) + { + QMutexLocker locker(singleton_guard()); + if (!mspInstance) + { + mspInstance = new LogManager; + // qAddPostRoutine(shutdown); + atexit(shutdown); + mspInstance->doConfigureLogLogger(); + mspInstance->welcome(); + mspInstance->doStartup(); + } + } + return mspInstance; + } + + + Logger *LogManager::logger(const QString &rName) + { + return instance()->mpLoggerRepository->logger(rName); + } + + + void LogManager::resetConfiguration() + { + setHandleQtMessages(false); + instance()->mpLoggerRepository->resetConfiguration(); + configureLogLogger(); + } + + + const char* LogManager::version() + { + return LOG4QT_VERSION_STR; + } + + + void LogManager::shutdown() + { + instance()->mpLoggerRepository->shutdown(); + } + + + void LogManager::doSetHandleQtMessages(bool handleQtMessages) + { + QMutexLocker locker(&mObjectGuard); + + if (instance()->mHandleQtMessages == handleQtMessages) + return; + + instance()->mHandleQtMessages = handleQtMessages; + if (instance()->mHandleQtMessages) + { + static_logger()->trace("Activate Qt message handling"); +#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0) + instance()->mOldQtMsgHandler = qInstallMsgHandler(qtMessageHandler); +#else + instance()->mOldQtMsgHandler = qInstallMessageHandler(qtMessageHandler); +#endif + } + else + { + static_logger()->trace("Deactivate Qt message handling"); +#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0) + qInstallMsgHandler(instance()->mOldQtMsgHandler); +#else + qInstallMessageHandler(instance()->mOldQtMsgHandler); +#endif + } + } + + + void LogManager::doConfigureLogLogger() + { + QMutexLocker locker(&instance()->mObjectGuard); + + // Level + QString value = InitialisationHelper::setting(QLatin1String("Debug"), + QLatin1String("ERROR")); + logLogger()->setLevel(OptionConverter::toLevel(value, Level::DEBUG_INT)); + + // Common layout + TTCCLayout *p_layout = new TTCCLayout(); + p_layout->setName(QLatin1String("LogLog TTCC")); + p_layout->setContextPrinting(false); + p_layout->activateOptions(); + + // Common deny all filter + Filter *p_denyall = new DenyAllFilter(); + p_denyall->activateOptions(); + + // ConsoleAppender on stdout for all events <= INFO + ConsoleAppender *p_appender; + LevelRangeFilter *p_filter; + p_appender = new ConsoleAppender(p_layout, ConsoleAppender::STDOUT_TARGET); + p_filter = new LevelRangeFilter(); + p_filter->setNext(p_denyall); + p_filter->setLevelMin(Level::NULL_INT); + p_filter->setLevelMax(Level::INFO_INT); + p_filter->activateOptions(); + p_appender->setName(QLatin1String("LogLog stdout")); + p_appender->addFilter(p_filter); + p_appender->activateOptions(); + logLogger()->addAppender(p_appender); + + // ConsoleAppender on stderr for all events >= WARN + p_appender = new ConsoleAppender(p_layout, ConsoleAppender::STDERR_TARGET); + p_filter = new LevelRangeFilter(); + p_filter->setNext(p_denyall); + p_filter->setLevelMin(Level::WARN_INT); + p_filter->setLevelMax(Level::OFF_INT); + p_filter->activateOptions(); + p_appender->setName(QLatin1String("LogLog stderr")); + p_appender->addFilter(p_filter); + p_appender->activateOptions(); + logLogger()->addAppender(p_appender); + } + + + void LogManager::doStartup() + { + QMutexLocker locker(&instance()->mObjectGuard); + + // Override + QString default_value = QLatin1String("false"); + QString value = InitialisationHelper::setting(QLatin1String("DefaultInitOverride"), + default_value); + if (value != default_value) + { + static_logger()->debug("DefaultInitOverride is set. Aborting default initialisation"); + return; + } + + // Configuration using setting Configuration + value = InitialisationHelper::setting(QLatin1String("Configuration")); + if (QFile::exists(value)) + { + static_logger()->debug("Default initialisation configures from file '%1' specified by Configure", value); + PropertyConfigurator::configure(value); + return; + } + + // Configuration using setting + if (QCoreApplication::instance()) + { + const QLatin1String log4qt_group("Log4Qt"); + const QLatin1String properties_group("Properties"); + QSettings s; + s.beginGroup(log4qt_group); + if (s.childGroups().contains(properties_group)) + { + const QString group(QLatin1String("Log4Qt/Properties")); + static_logger()->debug("Default initialisation configures from setting '%1/%2'", log4qt_group, properties_group); + s.beginGroup(properties_group); + PropertyConfigurator::configure(s); + return; + } + } + + // Configuration using default file + const QString default_file(QLatin1String("log4qt.properties")); + if (QFile::exists(default_file)) + { + static_logger()->debug("Default initialisation configures from default file '%1'", default_file); + PropertyConfigurator::configure(default_file); + return; + } + + static_logger()->debug("Default initialisation leaves package unconfigured"); + } + + + void LogManager::welcome() + { + static_logger()->info("Initialising Log4Qt %1", + QLatin1String(LOG4QT_VERSION_STR)); + + // Debug: Info + if (static_logger()->isDebugEnabled()) + { + // Create a nice timestamp with UTC offset + DateTime start_time = DateTime::fromMilliSeconds(InitialisationHelper::startTime()); + QString offset; + { + QDateTime utc = start_time.toUTC(); + QDateTime local = start_time.toLocalTime(); + QDateTime local_as_utc = QDateTime(local.date(), local.time(), Qt::UTC); + int min = utc.secsTo(local_as_utc) / 60; + if (min < 0) + offset += QLatin1Char('-'); + else + offset += QLatin1Char('+'); + min = abs(min); + offset += QString::number(min / 60).rightJustified(2, QLatin1Char('0')); + offset += QLatin1Char(':'); + offset += QString::number(min % 60).rightJustified(2, QLatin1Char('0')); + } + static_logger()->debug("Program startup time is %1 (UTC%2)", + start_time.toString(QLatin1String("ISO8601")), + offset); + static_logger()->debug("Internal logging uses the level %1", + logLogger()->level().toString()); + } + + // Trace: Dump settings + if (static_logger()->isTraceEnabled()) + { + static_logger()->trace("Settings from the system environment:"); + QString entry; + Q_FOREACH (entry, InitialisationHelper::environmentSettings().keys()) + static_logger()->trace(" %1: '%2'", + entry, + InitialisationHelper::environmentSettings().value(entry)); + + static_logger()->trace("Settings from the application settings:"); + if (QCoreApplication::instance()) + { + const QLatin1String log4qt_group("Log4Qt"); + const QLatin1String properties_group("Properties"); + static_logger()->trace(" %1:", log4qt_group); + QSettings s; + s.beginGroup(log4qt_group); + Q_FOREACH (entry, s.childKeys()) + static_logger()->trace(" %1: '%2'", + entry, + s.value(entry).toString()); + static_logger()->trace(" %1/%2:", log4qt_group, properties_group); + s.beginGroup(properties_group); + Q_FOREACH (entry, s.childKeys()) + static_logger()->trace(" %1: '%2'", + entry, + s.value(entry).toString()); + } else + static_logger()->trace(" QCoreApplication::instance() is not available"); + } + } + +#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0) + void LogManager::qtMessageHandler(QtMsgType type, const char *pMessage) + { + Level level; + switch (type) + { + case QtDebugMsg: + level = Level::DEBUG_INT; + break; + case QtWarningMsg: + level = Level::WARN_INT; + break; + case QtInfoMsg: + level = Level::INFO_INT; + break; + case QtCriticalMsg: + level = Level::ERROR_INT; + break; + case QtFatalMsg: + level = Level::FATAL_INT; + break; + default: + level = Level::TRACE_INT; + } + instance()->qtLogger()->log(level, pMessage); + + // Qt fatal behaviour copied from global.cpp qt_message_output() + // begin { + + if ((type == QtFatalMsg) || + ((type == QtWarningMsg) && (!qgetenv("QT_FATAL_WARNINGS").isNull())) ) + { +#if defined(Q_CC_MSVC) && defined(QT_DEBUG) && defined(_DEBUG) && defined(_CRT_ERROR) + // get the current report mode + int reportMode = _CrtSetReportMode(_CRT_ERROR, _CRTDBG_MODE_WNDW); + _CrtSetReportMode(_CRT_ERROR, reportMode); + int ret = _CrtDbgReport(_CRT_ERROR, __FILE__, __LINE__, QT_VERSION_STR, pMessage); + if (ret == 0 && reportMode & _CRTDBG_MODE_WNDW) + return; // ignore + else if (ret == 1) + _CrtDbgBreak(); +#endif + +#if defined(Q_OS_UNIX) && defined(QT_DEBUG) + abort(); // trap; generates core dump +#else + exit(1); // goodbye cruel world +#endif + } + + // } end + } +#else + void LogManager::qtMessageHandler(QtMsgType type, const QMessageLogContext &context, const QString &message) + { + Level level; + switch (type) + { + case QtDebugMsg: + level = Level::DEBUG_INT; + break; + case QtWarningMsg: + level = Level::WARN_INT; + break; + case QtInfoMsg: + level = Level::INFO_INT; + break; + case QtCriticalMsg: + level = Level::ERROR_INT; + break; + case QtFatalMsg: + level = Level::FATAL_INT; + break; + default: + level = Level::TRACE_INT; + } + QString newMsg = context.file?QString("%1:%2(%3)|").arg(context.file).arg(context.line).arg(context.function):"|"; + instance()->qtLogger()->log(level, newMsg+message); + + // Qt fatal behaviour copied from global.cpp qt_message_output() + // begin { + + if ((type == QtFatalMsg) || + ((type == QtWarningMsg) && (!qgetenv("QT_FATAL_WARNINGS").isNull())) ) + { +#if defined(Q_CC_MSVC) && defined(QT_DEBUG) && defined(_DEBUG) && defined(_CRT_ERROR) + // get the current report mode + int reportMode = _CrtSetReportMode(_CRT_ERROR, _CRTDBG_MODE_WNDW); + _CrtSetReportMode(_CRT_ERROR, reportMode); + int ret = _CrtDbgReport(_CRT_ERROR, __FILE__, __LINE__, QT_VERSION_STR, message.toUtf8().constData()); + if (ret == 0 && reportMode & _CRTDBG_MODE_WNDW) + return; // ignore + else if (ret == 1) + _CrtDbgBreak(); +#endif + +#if defined(Q_OS_UNIX) && defined(QT_DEBUG) + abort(); // trap; generates core dump +#else + exit(1); // goodbye cruel world +#endif + } + + // } end + } +#endif + + + + LogManager *LogManager::mspInstance = 0; + + + + /************************************************************************** + * Implementation: Operators, Helper + **************************************************************************/ + + +#ifndef QT_NO_DEBUG_STREAM + QDebug operator<<(QDebug debug, const LogManager &rLogManager) + { + Q_UNUSED(rLogManager); // To avoid warning C4100 on VS 2008 + QList loggers = rLogManager.loggers(); + debug.nospace() << "LogManager(" + << "loggerrepository:" << *rLogManager.loggerRepository() + << "log-level:" << rLogManager.logLogger()->level().toString() + << "log-appenders:" << rLogManager.logLogger()->appenders().count() + << "qt-level:" << rLogManager.qtLogger()->level().toString() + << "qt-appenders:" << rLogManager.qtLogger()->appenders().count() + << "handleqtmessages:" << rLogManager.handleQtMessages() + << ")"; + return debug.space(); + } +#endif // QT_NO_DEBUG_STREAM + + +} // namespace Log4Qt diff --git a/src/log4qt/log4qt/logmanager.h b/src/log4qt/log4qt/logmanager.h new file mode 100644 index 0000000..7911742 --- /dev/null +++ b/src/log4qt/log4qt/logmanager.h @@ -0,0 +1,341 @@ +/****************************************************************************** + * + * package: Log4Qt + * file: logmanager.h + * created: September 2007 + * author: Martin Heinrich + * + * + * Copyright 2007 Martin Heinrich + * + * 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. + * + ******************************************************************************/ + +#ifndef LOG4QT_LOGMANAGER_H +#define LOG4QT_LOGMANAGER_H + + +/****************************************************************************** + * Dependencies + ******************************************************************************/ + +#include + +#include +#include +#include +#include +#include "log4qt/level.h" +#include "log4qt/logger.h" +#include "ukui-logmacros.h" + + +/****************************************************************************** + * Declarations + ******************************************************************************/ + +namespace Log4Qt +{ + + class LoggerRepository; + + /*! + * \brief The class LogManager manages Logger in the default + * LoggerRepository. + * + * The LogManager manages logger in a single Hierarchy instance. It + * provides access to special logger over the logLogger(), qtLogger() + * and rootLogger() member functions. + * + * The LogManager is handling the initialisation on startup. The + * initialisation procedure will first attempt to configure the package + * based on environment variables. If the attempt fails it will check for + * the existence of configuration files in several location. For detailed + * description of the initialisation procedure see \ref Init + * "Initialization procedure". + * + * Messages created by qDebug(), qWarning(), qCritical() and qFatal() can + * be can be handled by the LogManager. By default the message handling + * is disabled. It can be enabled by calling setHandleQtMessages(). Once + * enabled all messages are logged using the logger qtLogger(). + * + * The Log4Qt runtime version is accessible over version(). The macros + * \ref Log4Qt::LOG4QT_VERSION "LOG4QT_VERSION" and + * \ref Log4Qt::LOG4QT_VERSION_STR "LOG4QT_VERSION_STR" provide the + * compile time version. + * + * \note All the functions declared in this class are thread-safe. + */ + class LIBUKUILOG4QT_EXPORT LogManager + { + private: + LogManager(); + LogManager(const LogManager &rOther); // Not implemented + virtual ~LogManager(); + LogManager &operator=(const LogManager &rOther); // Not implemented + + public: + /*! + * Returns if the handling of messages created by calls to qDebug(), + * qWarning(), qCritical() and qFatal() is activated. + * + * \sa setHandleQtMessages() + */ + static bool handleQtMessages(); + + static LoggerRepository *loggerRepository(); + + /*! + * Returns the logger used for logging internal messages. See + * \ref LogLog "Logging within the package" for more details. + * + * Calling this function is equivalent to calling logger("Log4Qt"). + */ + static Logger *logLogger(); + + /*! + * Returns a pointer to the logger used for logging messages created by + * calls to qDebug(), qWarning(), qCritical() and qFatal(). + * + * Calling this function is equivalent to calling logger("Qt"). + * + * \sa setHandleQtMessages() + */ + static Logger *qtLogger(); + + static Logger *rootLogger(); + static QList loggers(); + static Level threshold(); + static void setThreshold(Level level); + + /*! + * Activates or deactivates the handling of messages created by calls + * to qDebug(), qWarning(), qCritical() and qFatal() is activated. + * + * If activated, a Qt message handler is installed. Messages are logged + * using the logger returned by qtLogger(). For fatal messages the same + * exit procedure is implemented as for qFatal(). + * + * The following mappping is used from QtMsgType to Level: + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + *
    QtMsgType     %Level
QtDebugMsg Level::DEBUG_INT
QtWarningMsg Level::WARN_INT
QtCriticalMsg Level::ERROR_INT
QtFatalMsg Level::FATAL_INT
QtSystemMsg Level::TRACE_INT
+ * + * The default value is false for not handling Qt messages. + * + * \sa handleQtMessages(), qInstallMsgHandler(), qFatal() + */ + static void setHandleQtMessages(bool handleQtMessages); + + /*! + * Configures the logging for the package to its default behaviour. + * + * The logger logLogger() is configured to be not additive. Messages + * with the level Level::ERROR_INT and Level::FATAL_INT are written + * to \c stderr using a ConsoleAppender. The remaining messages are + * written to \c stdout using a second ConsoleAppender. The level is + * read from the system environment or application settings using + * InitialisationHelper::setting() with the key \c Debug. If a level + * value is found, but it is not a valid Level string, + * Level::DEBUG_INT is used. If no level string is found + * Level::ERROR_INT is used. + * + * The function does not remove any appender from the logger + * logLogger(). + * + * \sa \ref LogLog "Logging within the package", + * \ref Env "Environment Variables", + * resetConfiguration(), InitialisationHelper::setting() + */ + static void configureLogLogger(); + + static bool exists(const char *pName); + // JAVA: void fireAddAppenderEvent(Logger *pLogger, Appender *pAppender); + + /*! + * Returns the LogManager instance. + */ + static LogManager *instance(); + + static Logger *logger(const QString &rName); + + /*! + * Reset all values contained in logger repository to their default. + * + * All appenders are removed from all loggers. The loggers are handled + * in no particular order. The last loggers to be reset are qtLogger(), + * logLogger() and rootLogger() in that order. + * + * The handling of messages created by calls to qDebug(), qWarning(), + * qCritical() and qFatal() is deactivated. + * + * The internal logging is initialised to its default bahaviour + * using configureLogLogger(). + * + * \sa LoggerRepository::resetConfiguration(), setHandleQtMessages(), + * configureLogLogger() + */ + static void resetConfiguration(); + + static void shutdown(); + + /*! + * Executes the default initialisation procedure of the package. + * + * The function will test for the setting \c DefaultInitOverride in + * the system environment and application settings using + * \ref InitialisationHelper::setting(). If the value is present and + * set to anything else then \c false, the initialisation is aborted. + *
+ * The system environment and application settings are tested for the + * setting \c Configuration. If it is found and it is a valid path to + * a file, the package is configured with the file using + * \ref PropertyConfigurator::doConfigure(const QString &, LoggerRepository *) + * "PropertyConfigurator::doConfigure()". If the setting + * \c Configuration is not available and a QCoreApplication object is + * present, the application settings are tested for a group + * \c Log4Qt/Properties. If the group exists, the package is configured + * with the setting using the + * \ref PropertyConfigurator::doConfigure(const QSettings &r, LoggerRepository *) + * "PropertyConfiguratordoConfigure()". If neither a configuration + * file nor configuration settings could be found, the current working + * directory is searched for the file \c "log4qt.properties". If it is + * found, the package is configured with the file using + * \ref PropertyConfigurator::doConfigure(const QString &, LoggerRepository *) + * "PropertyConfigurator::doConfigure()". + * + * \sa \ref Init "Initialization procedure", + * \ref Env "Environment Variables", + * InitialisationHelper::setting() + */ + static void startup(); + + /*! + * Returns the version number of Log4Qt at run-time. This may be a + * different version than the version the application was compiled + * against. + * + * \sa \ref Log4Qt::LOG4QT_VERSION "LOG4QT_VERSION", + * \ref Log4Qt::LOG4QT_VERSION_STR "LOG4QT_VERSION_STR" + + */ + static const char* version(); + + private: + void doSetHandleQtMessages(bool handleQtMessages); + void doConfigureLogLogger(); + void doStartup(); + void welcome(); +#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0) + static void qtMessageHandler(QtMsgType type, + const char *pMessage); +#else + static void qtMessageHandler(QtMsgType type, + const QMessageLogContext &context, + const QString &message); +#endif + + + private: + mutable QMutex mObjectGuard; + LoggerRepository *mpLoggerRepository; + Logger *mpNullLogger; + bool mHandleQtMessages; +#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0) + QtMsgHandler mOldQtMsgHandler; +#else + QtMessageHandler mOldQtMsgHandler; +#endif + static LogManager *mspInstance; + }; + + + /*************************************************************************** + * Operators, Helper + ***************************************************************************/ + + #ifndef QT_NO_DEBUG_STREAM + /*! + * \relates LogManager + * + * Writes all object member variables to the given debug stream \a rDebug and + * returns the stream. + * + * + * %LogManager(loggerrepository:Hierarchy(loggers:6 root-level:"DEBUG" + * root-appenders:0 log-level: "NULL" log-appenders:0 + * qt-level: "NULL" qt-appenders:0 handleqtmessages: false ) + * + * \sa QDebug + */ + QDebug operator<<(QDebug debug, + const LogManager &rLogManager); + #endif // QT_NO_DEBUG_STREAM + + + /************************************************************************** + * Inline + **************************************************************************/ + + inline LoggerRepository *LogManager::loggerRepository() + { // QMutexLocker locker(&instance()->mObjectGuard); // Constant for object lifetime + return instance()->mpLoggerRepository; } + + inline bool LogManager::handleQtMessages() + { // QMutexLocker locker(&instance()->mObjectGuard); // Read/Write of bool is safe + return instance()->mHandleQtMessages; } + + inline Logger *LogManager::logLogger() + { // QMutexLocker locker(&instance()->mObjectGuard); // Constant for object lifetime + return logger(QLatin1String("Log4Qt")); } + + inline Logger *LogManager::qtLogger() + { // QMutexLocker locker(&instance()->mObjectGuard); // Constant for object lifetime + return logger(QLatin1String("Qt")); } + + inline void LogManager::setHandleQtMessages(bool handleQtMessages) + { instance()->doSetHandleQtMessages(handleQtMessages); } + + inline void LogManager::configureLogLogger() + { instance()->doConfigureLogLogger(); } + + inline void LogManager::startup() + { instance()->doStartup(); } + +} // namespace Log4Qt + + +// Q_DECLARE_TYPEINFO(Log4Qt::LogManager, Q_COMPLEX_TYPE); // Use default + + +#endif // LOG4QT_LOGMANAGER_H diff --git a/src/log4qt/log4qt/mdc.cpp b/src/log4qt/log4qt/mdc.cpp new file mode 100644 index 0000000..5ba2ba8 --- /dev/null +++ b/src/log4qt/log4qt/mdc.cpp @@ -0,0 +1,116 @@ +/****************************************************************************** + * + * package: Log4Qt + * file: mdc.cpp + * created: September 2007 + * author: Martin Heinrich + * + * + * changes Feb 2009, Martin Heinrich + * - Fixed unreferenced formal parameter warning by using + * Q_UNUSED in operator<<. + * + * + * Copyright 2007 - 2009 Martin Heinrich + * + * 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. + * + *****************************************************************************/ + + + +/****************************************************************************** + * Dependencies + ******************************************************************************/ + + +#include "log4qt/mdc.h" + +#include +#include +#include +#include "log4qt/helpers/initialisationhelper.h" +#include "log4qt/logger.h" + + + +namespace Log4Qt +{ + + + /************************************************************************** + * Declarations + **************************************************************************/ + + + + /************************************************************************** + * C helper functions + **************************************************************************/ + + + + /************************************************************************** + * Class implementation: MDC + **************************************************************************/ + + + QString MDC::get(const QString &rKey) + { + if (!instance()->mHash.hasLocalData()) + return QString(); + + return instance()->mHash.localData()->value(rKey); + } + + + QHash MDC::context() + { + if (!instance()->mHash.hasLocalData()) + return QHash(); + + return *instance()->mHash.localData(); + } + + + LOG4QT_IMPLEMENT_INSTANCE(MDC) + + + QHash *MDC::localData() + { + if (!instance()->mHash.hasLocalData()) + instance()->mHash.setLocalData(new QHash); + return instance()->mHash.localData(); + } + + + + /************************************************************************** + * Implementation: Operators, Helper + **************************************************************************/ + + +#ifndef QT_NO_DEBUG_STREAM + QDebug operator<<(QDebug debug, const MDC &rMDC) + { + Q_UNUSED(rMDC); // To avoid warning C4100 on VS 2008 + debug.nospace() << "MDC(" + << "thread:" << QThread::currentThread()->objectName() << " " + << "context:" << rMDC.context() + << ")"; + return debug.space(); + } +#endif // QT_NO_DEBUG_STREAM + + +} // namespace Log4Qt diff --git a/src/log4qt/log4qt/mdc.h b/src/log4qt/log4qt/mdc.h new file mode 100644 index 0000000..abed318 --- /dev/null +++ b/src/log4qt/log4qt/mdc.h @@ -0,0 +1,123 @@ +/****************************************************************************** + * + * package: Log4Qt + * file: mdc.h + * created: September 2007 + * author: Martin Heinrich + * + * + * Copyright 2007 Martin Heinrich + * + * 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. + * + ******************************************************************************/ + +#ifndef LOG4QT_MDC_H +#define LOG4QT_MDC_H + + +/****************************************************************************** + * Dependencies + ******************************************************************************/ + +#include +#include +#include +#include "log4qt/log4qt.h" +#include "ukui-logmacros.h" + + +/****************************************************************************** + * Declarations + ******************************************************************************/ + +namespace Log4Qt +{ + + +/*! + * \brief The class MDC implements a mapped diagnostic context. + * + * \note All the functions declared in this class are thread-safe. + */ + class LIBUKUILOG4QT_EXPORT MDC + { + private: + MDC(); + MDC(const MDC &rOther); // Not implemented + // virtual ~MDC(); // Use compiler default + MDC &operator=(const MDC &rOther); // Not implemented + + public: + static QString get(const QString &rKey); + static QHash context(); + + /*! + * Returns the MDC instance. + */ + static MDC *instance(); + + static void put(const QString &rKey, const QString &rValue); + static void remove(const QString &rKey); + + private: + static QHash *localData(); + + private: + QThreadStorage< QHash * > mHash; + }; + + + /************************************************************************** + * Operators, Helper + **************************************************************************/ + + #ifndef QT_NO_DEBUG_STREAM + /*! + * \relates MDC + * + * Writes all object member variables to the given debug stream \a rDebug + * and returns the stream. + * + * + * %MDC(thread:"main" context:QHash(("login", "Peter")("database", "UAT")) ) + * + * \sa QDebug + */ + QDebug operator<<(QDebug debug, + const MDC &rMDC); + #endif // QT_NO_DEBUG_STREAM + + + /************************************************************************** + * Inline + **************************************************************************/ + + inline MDC::MDC() : + mHash() + {} + + inline void MDC::put(const QString &rKey, const QString &rValue) + { localData()->insert(rKey, rValue); } + + inline void MDC::remove(const QString &rKey) + { localData()->remove(rKey); } + + +} // namespace Log4Qt + + +// Q_DECLARE_TYPEINFO(Log4Qt::MDC, Q_COMPLEX_TYPE); // Use default + + +#endif // LOG4QT_MDC_H diff --git a/src/log4qt/log4qt/ndc.cpp b/src/log4qt/log4qt/ndc.cpp new file mode 100644 index 0000000..17ebd47 --- /dev/null +++ b/src/log4qt/log4qt/ndc.cpp @@ -0,0 +1,154 @@ +/****************************************************************************** + * + * package: Log4Qt + * file: ndc.cpp + * created: September 2007 + * author: Martin Heinrich + * + * + * changes Feb 2009, Martin Heinrich + * - Fixed VS 2008 unreferenced formal parameter warning by using + * Q_UNUSED in operator<<. + * + * + * Copyright 2007 - 2009 Martin Heinrich + * + * 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. + * + *****************************************************************************/ + + + +/****************************************************************************** + * Dependencies + ******************************************************************************/ + + +#include "log4qt/ndc.h" + +#include +#include +#include +#include "log4qt/helpers/initialisationhelper.h" +#include "log4qt/logger.h" + + + +namespace Log4Qt +{ + + + /************************************************************************** + * Declarations + **************************************************************************/ + + + + /************************************************************************** + * C helper functions + **************************************************************************/ + + + LOG4QT_DECLARE_STATIC_LOGGER(logger, Log4Qt:NDC) + + + + /************************************************************************** + * Class implementation: NDC + **************************************************************************/ + + + void NDC::clear() + { + if (!instance()->mStack.hasLocalData()) + return; + + instance()->mStack.localData()->clear(); + } + + + int NDC::depth() + { + if (!instance()->mStack.hasLocalData()) + return 0; + + return instance()->mStack.localData()->count(); + } + + + LOG4QT_IMPLEMENT_INSTANCE(NDC) + + + QString NDC::pop() + { + if (!instance()->mStack.hasLocalData() || instance()->mStack.localData()->isEmpty()) + { + logger()->warn("Requesting pop from empty NDC stack"); + return QString(); + } + + return instance()->mStack.localData()->pop(); + } + + + void NDC::push(const QString &rMessage) + { + if (!instance()->mStack.hasLocalData()) + instance()->mStack.setLocalData(new QStack); + + instance()->mStack.localData()->push(rMessage); + } + + + void NDC::setMaxDepth(int maxDepth) + { + if (!instance()->mStack.hasLocalData() || + instance()->mStack.localData()->size() <= maxDepth) + return; + + instance()->mStack.localData()->resize(maxDepth); + } + + + QString NDC::peek() + { + if (!instance()->mStack.hasLocalData() || + instance()->mStack.localData()->isEmpty()) + return QString(); + + return instance()->mStack.localData()->top(); + } + + + + /************************************************************************** + * Implementation: Operators, Helper + **************************************************************************/ + + +#ifndef QT_NO_DEBUG_STREAM + QDebug operator<<(QDebug debug, + const NDC &rNDC) + { + Q_UNUSED(rNDC); // To avoid warning C4100 on VS 2008 + debug.nospace() << "NDC(" + << "thread:" << QThread::currentThread()->objectName() << " " + << "peek:" << rNDC.peek() << " " + << "depth:" << rNDC.depth() + << ")"; + return debug.space(); + } +#endif // QT_NO_DEBUG_STREAM + + +} // namespace Log4Qt diff --git a/src/log4qt/log4qt/ndc.h b/src/log4qt/log4qt/ndc.h new file mode 100644 index 0000000..87437cc --- /dev/null +++ b/src/log4qt/log4qt/ndc.h @@ -0,0 +1,122 @@ +/****************************************************************************** + * + * package: Log4Qt + * file: ndc.h + * created: September 2007 + * author: Martin Heinrich + * + * + * Copyright 2007 Martin Heinrich + * + * 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. + * + ******************************************************************************/ + +#ifndef LOG4QT_NDC_H +#define LOG4QT_NDC_H + + +/****************************************************************************** + * Dependencies + ******************************************************************************/ + +#include +#include +#include +#include "log4qt/log4qt.h" +#include "ukui-logmacros.h" + + +/****************************************************************************** + * Declarations + ******************************************************************************/ + +namespace Log4Qt +{ + + /*! + * \brief The class NDC implements a nested diagnostic context. + * + * The method remove() is not required. QThreadStorage cleans up on thread + * exit. + * + * \note All the functions declared in this class are thread-safe. + */ + class LIBUKUILOG4QT_EXPORT NDC + { + private: + NDC(); + NDC(const NDC &rOther); // Not implemented + // virtual ~NDC(); // Use compiler default + NDC &operator=(const NDC &rOther); // Not implemented + + public: + static void clear(); + // JAVA: static QStack cloneStack(); + // JAVA: static QString get(); + static int depth(); + // JAVA: inherit(Stack stack) + + /*! + * Returns the NDC instance. + */ + static NDC *instance(); + + static QString pop(); + static void push(const QString &rMessage); + // JAVA: static void remove(); // Not required + static void setMaxDepth(int maxDepth); + static QString peek(); + + private: + QThreadStorage< QStack * > mStack; + }; + + + /****************************************************************************** + * Operators, Helper + ******************************************************************************/ + + #ifndef QT_NO_DEBUG_STREAM + /*! + * \relates NDC + * + * Writes all object member variables to the given debug stream \a rDebug and + * returns the stream. + * + * + * %NDC(thread:"main" peek:"i = 3" depth:4) + * + * \sa QDebug + */ + QDebug operator<<(QDebug debug, + const NDC &rNDC); + #endif // QT_NO_DEBUG_STREAM + + + /****************************************************************************** + * Inline + ******************************************************************************/ + + inline NDC::NDC() : + mStack() + {} + + +} // namespace Log4Qt + + +// Q_DECLARE_TYPEINFO(Log4Qt::NDC, Q_COMPLEX_TYPE); // Use default + + +#endif // LOG4QT_NDC_H diff --git a/src/log4qt/log4qt/patternlayout.cpp b/src/log4qt/log4qt/patternlayout.cpp new file mode 100644 index 0000000..a93099f --- /dev/null +++ b/src/log4qt/log4qt/patternlayout.cpp @@ -0,0 +1,147 @@ +/****************************************************************************** + * + * package: Log4Qt + * file: patternlayout.cpp + * created: September 2007 + * author: Martin Heinrich + * + * + * Copyright 2007 Martin Heinrich + * + * 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. + * + ******************************************************************************/ + + + +/****************************************************************************** + * Dependencies + ******************************************************************************/ + + +#include "log4qt/patternlayout.h" + +#include +#include "log4qt/helpers/patternformatter.h" +#include "log4qt/loggingevent.h" + + + +namespace Log4Qt +{ + + + /************************************************************************** + * Declarations + **************************************************************************/ + + + + /************************************************************************** + * C helper functions + **************************************************************************/ + + + + /************************************************************************** + * Class implementation: PatternLayout + **************************************************************************/ + + + PatternLayout::PatternLayout(QObject *pParent) : + Layout(pParent), + mPattern(), + mpPatternFormatter(0) + { + setConversionPattern(DEFAULT_CONVERSION_PATTERN); + } + + + PatternLayout::PatternLayout(const QString &rPattern, + QObject *pParent) : + Layout(pParent), + mPattern(), + mpPatternFormatter(0) + { + setConversionPattern(rPattern); + } + + + PatternLayout::PatternLayout(ConversionPattern conversionPattern, + QObject *pParent) : + Layout(pParent), + mPattern(), + mpPatternFormatter(0) + { + setConversionPattern(conversionPattern); + } + + + PatternLayout::~PatternLayout() + { + delete mpPatternFormatter; + } + + + void PatternLayout::setConversionPattern(ConversionPattern conversionPattern) + { + switch (conversionPattern) + { + case DEFAULT_CONVERSION_PATTERN: + setConversionPattern(QLatin1String("%m%n")); + break; + case TTCC_CONVERSION_PATTERN: + setConversionPattern(QLatin1String("%r [%t] %p %c %x - %m%n")); + break; + default: + Q_ASSERT_X(false, "PatternLayout::setConversionFormat", "Unkown ConversionFormat"); + setConversionPattern(QString()); + } + } + + + QString PatternLayout::format(const LoggingEvent &rEvent) + { + Q_ASSERT_X(mpPatternFormatter, "PatternLayout::format()", "mpPatternConverter must not be null"); + + return mpPatternFormatter->format(rEvent); + } + + + void PatternLayout::updatePatternFormatter() + { + delete mpPatternFormatter; + mpPatternFormatter = new PatternFormatter(mPattern); + } + + +#ifndef QT_NO_DEBUG_STREAM + QDebug PatternLayout::debug(QDebug &rDebug) const + { + rDebug.nospace() << "PatternLayout(" + << "name:" << name() << " " + << "pattern:" << conversionPattern() << " " + << "referencecount:" << referenceCount() + << ")"; + return rDebug.space(); + } +#endif // QT_NO_DEBUG_STREAM + + + + /************************************************************************** + * Implementation: Operators, Helper + **************************************************************************/ + + +} // namespace Log4Qt diff --git a/src/log4qt/log4qt/patternlayout.h b/src/log4qt/log4qt/patternlayout.h new file mode 100644 index 0000000..86dca43 --- /dev/null +++ b/src/log4qt/log4qt/patternlayout.h @@ -0,0 +1,160 @@ +/****************************************************************************** + * + * package: Log4Qt + * file: patternlayout.h + * created: September 2007 + * author: Martin Heinrich + * + * + * Copyright 2007 Martin Heinrich + * + * 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. + * + ******************************************************************************/ + +#ifndef LOG4QT_PATTERNLAYOUT_H +#define LOG4QT_PATTERNLAYOUT_H + + +/****************************************************************************** + * Dependencies + ******************************************************************************/ + +#include "log4qt/layout.h" +#include "ukui-logmacros.h" + + +/****************************************************************************** + * Declarations + ******************************************************************************/ + + +namespace Log4Qt +{ + + class PatternFormatter; + + /*! + * \brief The class PatternLayout outputs a logging event based on a + * pattern string. + * + * \note The ownership and lifetime of objects of this class are managed. + * See \ref Ownership "Object ownership" for more details. + */ + class LIBUKUILOG4QT_EXPORT PatternLayout : public Layout + { + Q_OBJECT + + /*! + * The property holds the conversion pattern used by the appender. + * + * The default is "%m%n". + * + * \sa conversionPattern(), setConversionPattern() + */ + Q_PROPERTY(QString conversionPattern READ conversionPattern WRITE setConversionPattern) + + public: + /*! + * The enum ConversionPattern defines constants for pattern strings. + * + * \sa setConversionPattern(ConversionPattern); + */ + enum ConversionPattern + { + /*! The default conversion pattern string is "%m,%n". */ + DEFAULT_CONVERSION_PATTERN, + /*! + * The ttcc conversion pattern string is + * "%r [%t] %p %c %x - %m%n". + */ + TTCC_CONVERSION_PATTERN, + }; + Q_ENUMS(ConversionPattern) + + PatternLayout(QObject *pParent = 0); + PatternLayout(const QString &rPattern, + QObject *pParent = 0); + + /*! + * Creates a PatternLayout with the conversion pattern value specified + * by the \a conversionPattern constant. + */ + PatternLayout(ConversionPattern conversionPattern, + QObject *pParent = 0); + + virtual ~PatternLayout(); + private: + PatternLayout(const PatternLayout &rOther); // Not implemented + PatternLayout &operator=(const PatternLayout &rOther); // Not implemented + + public: + QString conversionPattern() const; + void setConversionPattern(const QString &rPattern); + + /*! + * Sets the conversion pattern to the value specified by the + * \a conversionPattern constant. + */ + void setConversionPattern(ConversionPattern conversionPattern); + + virtual QString format(const LoggingEvent &rEvent); + + protected: +#ifndef QT_NO_DEBUG_STREAM + /*! + * Writes all object member variables to the given debug stream + * \a rDebug and returns the stream. + * + * + * %PatternLayout(name:"PL" pattern:"%r [%t] %p %c %x - %m%n" + * "referencecount:3") + * + * \sa QDebug, operator<<(QDebug debug, const LogObject &rLogObject) + */ + virtual QDebug debug(QDebug &rDebug) const; +#endif // QT_NO_DEBUG_STREAM + + private: + void updatePatternFormatter(); + + private: + QString mPattern; + PatternFormatter *mpPatternFormatter; + }; + + + /************************************************************************** + * Operators, Helper + **************************************************************************/ + + + /************************************************************************** + * Inline + **************************************************************************/ + + inline QString PatternLayout::conversionPattern() const + { return PatternLayout::mPattern; } + + inline void PatternLayout::setConversionPattern(const QString &rPattern) + { mPattern = rPattern; + updatePatternFormatter(); } + + +} // namespace Log4Qt + + +// Q_DECLARE_TYPEINFO(Log4Qt::PatternLayout, Q_COMPLEX_TYPE); // Use default + + +#endif // LOG4QT_PATTERNLAYOUT_H diff --git a/src/log4qt/log4qt/propertyconfigurator.cpp b/src/log4qt/log4qt/propertyconfigurator.cpp new file mode 100644 index 0000000..19b7113 --- /dev/null +++ b/src/log4qt/log4qt/propertyconfigurator.cpp @@ -0,0 +1,588 @@ +/****************************************************************************** + * + * package: Logging + * file: propertyconfigurator.cpp + * created: September 2007 + * author: Martin Heinrich + * + * + * changes Feb 2009, Martin Heinrich + * - Fixed VS 2008 unreferenced formal parameter warning by using + * Q_UNUSED in operator<<. + * + * + * Copyright 2007 - 2009 Martin Heinrich + * + * 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. + * + ******************************************************************************/ + + + +/****************************************************************************** + * Dependencies + ******************************************************************************/ + + +#include "log4qt/propertyconfigurator.h" + +#include +#include +#include "log4qt/helpers/configuratorhelper.h" +#include "log4qt/helpers/factory.h" +#include "log4qt/helpers/optionconverter.h" +#include "log4qt/helpers/properties.h" +#include "log4qt/appender.h" +#include "log4qt/layout.h" +#include "log4qt/logger.h" +#include "log4qt/logmanager.h" +#include "log4qt/loggerrepository.h" +#include "log4qt/varia/listappender.h" + + + +namespace Log4Qt +{ + + + /************************************************************************** + * Declarations + **************************************************************************/ + + + + /************************************************************************** + * C helper functions + **************************************************************************/ + + + LOG4QT_DECLARE_STATIC_LOGGER(logger, Log4Qt::PropertyConfigurator) + + + + /************************************************************************** + * Class implementation: PropertyConfigurator + **************************************************************************/ + + + bool PropertyConfigurator::doConfigure(const Properties &rProperties, + LoggerRepository *pLoggerRepository) + { + startCaptureErrors(); + configureFromProperties(rProperties, pLoggerRepository); + return stopCaptureErrors(); + } + + + bool PropertyConfigurator::doConfigure(const QString &rConfigFileName, + LoggerRepository *pLoggerRepository) + { + startCaptureErrors(); + configureFromFile(rConfigFileName, pLoggerRepository); + return stopCaptureErrors(); + } + + + bool PropertyConfigurator::doConfigure(const QSettings &rSettings, + LoggerRepository *pLoggerRepository) + { + startCaptureErrors(); + configureFromSettings(rSettings, pLoggerRepository); + return stopCaptureErrors(); + } + + + bool PropertyConfigurator::configure(const Properties &rProperties) + { + PropertyConfigurator configurator; + return configurator.doConfigure(rProperties); + } + + + bool PropertyConfigurator::configure(const QString &rConfigFilename) + { + PropertyConfigurator configurator; + return configurator.doConfigure(rConfigFilename); + } + + + bool PropertyConfigurator::configure(const QSettings &rSettings) + { + PropertyConfigurator configurator; + return configurator.doConfigure(rSettings); + } + + + bool PropertyConfigurator::configureAndWatch(const QString &rConfigFileName) + { + // Stop an existing watch to avoid a possible concurrent configuration + ConfiguratorHelper::setConfigurationFile(); + if (rConfigFileName.isEmpty()) + return true; + + PropertyConfigurator configurator; + bool result = configurator.doConfigure(rConfigFileName); + ConfiguratorHelper::setConfigurationFile(rConfigFileName, configure); + return result; + } + + + void PropertyConfigurator::configureFromFile(const QString &rConfigFileName, + LoggerRepository *pLoggerRepository) + { + QFile file(rConfigFileName); + if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) + { + LogError e = LOG4QT_ERROR(QT_TR_NOOP("Unable to open property file '%1'"), + CONFIGURATOR_OPENING_FILE_ERROR, + "Log4Qt::PropertyConfigurator"); + e << rConfigFileName; + e.addCausingError(LogError(file.errorString(), file.error())); + logger()->error(e); + return; + } + Properties properties; + properties.load(&file); + if (file.error()) + { + LogError e = LOG4QT_ERROR(QT_TR_NOOP("Unable to read property file '%1'"), + CONFIGURATOR_READING_FILE_ERROR, + "Log4Qt::PropertyConfigurator"); + e << rConfigFileName; + e.addCausingError(LogError(file.errorString(), file.error())); + logger()->error(e); + return; + } + configureFromProperties(properties, pLoggerRepository); + } + + + void PropertyConfigurator::configureFromProperties(const Properties &rProperties, + LoggerRepository *pLoggerRepository) + { + if (!pLoggerRepository) + pLoggerRepository = LogManager::loggerRepository(); + + configureGlobalSettings(rProperties, pLoggerRepository); + configureRootLogger(rProperties, pLoggerRepository); + configureNonRootElements(rProperties, pLoggerRepository); + mAppenderRegistry.clear(); + } + + + void PropertyConfigurator::configureFromSettings(const QSettings &rSettings, + LoggerRepository *pLoggerRepository) + { + Properties properties; + properties.load(rSettings); + configureFromProperties(properties, pLoggerRepository); + } + + + void PropertyConfigurator::configureGlobalSettings(const Properties &rProperties, + LoggerRepository *pLoggerRepository) const + { + Q_ASSERT_X(pLoggerRepository, "PropertyConfigurator::configureGlobalSettings()", "pLoggerRepository must not be null."); + + const QLatin1String key_reset("log4j.reset"); + const QLatin1String key_debug("log4j.Debug"); + const QLatin1String key_config_debug("log4j.configDebug"); + const QLatin1String key_threshold("log4j.threshold"); + const QLatin1String key_handle_qt_messages("log4j.handleQtMessages"); + + // Test each global setting and set it + // - Reset: log4j.reset + // - Debug: log4j.Debug, log4j.configDebug + // - Threshold: log4j.threshold + // - Handle Qt Messages: log4j.handleQtMessages + + // Reset + QString value = rProperties.property(key_reset); + if (!value.isEmpty() && OptionConverter::toBoolean(value, false)) + { + // Use LogManager and not pLoggerRepository to reset internal + // logging. + LogManager::resetConfiguration(); + logger()->debug("Reset configuration"); + } + + // Debug + value = rProperties.property(key_debug); + if (value.isNull()) + { + value = rProperties.property(key_config_debug); + if (!value.isNull()) + logger()->warn("[%1] is deprecated. Use [%2] instead.", key_config_debug, key_debug); + } + if (!value.isNull()) + { + // Don't use OptionConverter::toLevel(). Invalid level string is a valid setting + bool ok; + Level level = Level::fromString(value, &ok); + if (!ok) + level = Level::DEBUG_INT; + LogManager::logLogger()->setLevel(level); + logger()->debug("Set level for Log4Qt logging to %1", + LogManager::logLogger()->level().toString()); + } + + // Threshold + value = rProperties.property(key_threshold); + if (!value.isNull()) + { + pLoggerRepository->setThreshold(OptionConverter::toLevel(value, Level::ALL_INT)); + logger()->debug("Set threshold for LoggerRepository to %1", + pLoggerRepository->threshold().toString()); + } + + // Handle Qt messages + value = rProperties.property(key_handle_qt_messages); + if (!value.isNull()) + { + LogManager::setHandleQtMessages(OptionConverter::toBoolean(value, false)); + logger()->debug("Set handling of Qt messages LoggerRepository to %1", + QVariant(LogManager::handleQtMessages()).toString()); + } + } + + + void PropertyConfigurator::configureNonRootElements(const Properties &rProperties, + LoggerRepository *pLoggerRepository) + { + Q_ASSERT_X(pLoggerRepository, "PropertyConfigurator::configureNonRootElements()", "pLoggerRepository must not be null."); + + const QString logger_prefix = QLatin1String("log4j.logger."); + const QString category_prefix = QLatin1String("log4j.category."); + + // Iterate through all entries: + // - Test for the logger/category prefix + // - Convert JAVA class names to C++ ones + // - Parse logger data (Level, Appender) + // - Parse logger additivity + + QStringList keys = rProperties.propertyNames(); + QString key; + Q_FOREACH(key, keys) + { + QString java_name; + if (key.startsWith(logger_prefix)) + java_name = key.mid(logger_prefix.length()); + else if (key.startsWith(category_prefix)) + java_name = key.mid(category_prefix.length()); + QString cpp_name = OptionConverter::classNameJavaToCpp(java_name); + if (!java_name.isEmpty()) + { + Logger *p_logger = pLoggerRepository->logger(cpp_name); + QString value = OptionConverter::findAndSubst(rProperties, key); + parseLogger(rProperties, p_logger, key, value); + parseAdditivityForLogger(rProperties, p_logger, java_name); + } + } + } + + + void PropertyConfigurator::configureRootLogger(const Properties &rProperties, + LoggerRepository *pLoggerRepository) + { + Q_ASSERT_X(pLoggerRepository, "PropertyConfigurator::configureRootLogger()", "pLoggerRepository must not be null."); + + const QLatin1String key_root_logger("log4j.rootLogger"); + const QLatin1String key_root_category("log4j.rootCategory"); + + // - Test for the logger/category prefix + // - Parse logger data for root logger + + QString key = key_root_logger; + QString value = OptionConverter::findAndSubst(rProperties, key); + if (value.isNull()) + { + key = key_root_category; + value = OptionConverter::findAndSubst(rProperties, key); + if (!value.isNull()) + logger()->warn("[%1] is deprecated. Use [%2] instead.", key_root_category, key_root_logger); + } + + if (value.isNull()) + logger()->debug("Could not find root logger information. Is this correct?"); + else + parseLogger(rProperties, pLoggerRepository->rootLogger(), key, value); + } + + + void PropertyConfigurator::parseAdditivityForLogger(const Properties &rProperties, + Logger *pLogger, + const QString &rLog4jName) const + { + Q_ASSERT_X(pLogger, "parseAdditivityForLogger()", "pLogger must not be null."); + + const QLatin1String additivity_prefix("log4j.additivity."); + + // - Lookup additivity key for logger + // - Set additivity, if specified + + QString key = additivity_prefix + rLog4jName; + QString value = OptionConverter::findAndSubst(rProperties, key); + logger()->debug("Parsing additivity for logger: key '%1', value '%2'", key, value); + if (!value.isEmpty()) + { + bool additivity = OptionConverter::toBoolean(value, true); + logger()->debug("Setting additivity for logger '%1' to '%2'", pLogger->name(), QVariant(value).toString()); + pLogger->setAdditivity(additivity); + } + } + + + LogObjectPtr PropertyConfigurator::parseAppender(const Properties &rProperties, + const QString &rName) + { + // - Test if appender has been parsed before + // - Find appender key + // - Create appender object + // - Set layout, if required by appender + // - Set properties + // - Activate options + // - Add appender to registry + + const QLatin1String appender_prefix("log4j.appender."); + + logger()->debug("Parsing appender named '%1'", rName); + + if (mAppenderRegistry.contains(rName)) + { + logger()->debug("Appender '%1' was already parsed.", rName); + return mAppenderRegistry.value(rName); + } + + QString key = appender_prefix + rName; + QString value = OptionConverter::findAndSubst(rProperties, key); + if (value.isNull()) + { + LogError e = LOG4QT_ERROR(QT_TR_NOOP("Missing appender definition for appender named '%1'"), + CONFIGURATOR_MISSING_APPENDER_ERROR, + "Log4Qt::PropertyConfigurator"); + e << rName; + logger()->error(e); + return 0; + } + LogObjectPtr p_appender = Factory::createAppender(value); + if (!p_appender) + { + LogError e = LOG4QT_ERROR(QT_TR_NOOP("Unable to create appender of class '%1' namd '%2'"), + CONFIGURATOR_UNKNOWN_APPENDER_CLASS_ERROR, + "Log4Qt::PropertyConfigurator"); + e << value << rName; + logger()->error(e); + return 0; + } + p_appender->setName(rName); + + if (p_appender->requiresLayout()) + { + LogObjectPtr p_layout = parseLayout(rProperties, key); + if (p_layout) + p_appender->setLayout(p_layout); + else + return 0; + } + + QStringList exclusions; + exclusions << QLatin1String("layout"); + setProperties(rProperties, key + QLatin1String("."), exclusions, p_appender); + AppenderSkeleton *p_appenderskeleton = qobject_cast(p_appender); + if (p_appenderskeleton) + p_appenderskeleton->activateOptions(); + + mAppenderRegistry.insert(rName, p_appender); + return p_appender; + } + + + LogObjectPtr PropertyConfigurator::parseLayout(const Properties &rProperties, + const QString &rAppenderKey) + { + Q_ASSERT_X(!rAppenderKey.isEmpty(), "PropertyConfigurator::parseLayout()", "rAppenderKey must not be empty."); + + // - Find layout key + // - Create layput object + // - Set properties + // - Activate options + + const QLatin1String layout_suffix(".layout"); + + logger()->debug("Parsing layout for appender named '%1'", rAppenderKey); + + QString key = rAppenderKey + layout_suffix; + QString value = OptionConverter::findAndSubst(rProperties, key); + if (value.isNull()) + { + LogError e = LOG4QT_ERROR(QT_TR_NOOP("Missing layout definition for appender '%1'"), + CONFIGURATOR_MISSING_LAYOUT_ERROR, + "Log4Qt::PropertyConfigurator"); + e << rAppenderKey; + logger()->error(e); + return 0; + } + LogObjectPtr p_layout = Factory::createLayout(value); + if (!p_layout) + { + LogError e = LOG4QT_ERROR(QT_TR_NOOP("Unable to create layoput of class '%1' requested by appender '%2'"), + CONFIGURATOR_UNKNOWN_LAYOUT_CLASS_ERROR, + "Log4Qt::PropertyConfigurator"); + e << value << rAppenderKey; + logger()->error(e); + return 0; + } + + QStringList exclusions; + setProperties(rProperties, key + QLatin1String("."), QStringList(), p_layout); + p_layout->activateOptions(); + + return p_layout; + } + + + void PropertyConfigurator::parseLogger(const Properties &rProperties, + Logger *pLogger, + const QString &rKey, + const QString &rValue) + { + Q_ASSERT_X(pLogger, "PropertyConfigurator::parseLogger()", "pLogger must not be null."); + Q_ASSERT_X(!rKey.isEmpty(), "PropertyConfigurator::parseLogger()", "rKey must not be empty."); + + const QLatin1String keyword_inherited("INHERITED"); + + // - Split value on comma + // - If level value, is specified + // - Test for NULL and INHERITED + // - Ensure root logger is not set to NULL + // - Set level + // - For each entry + // - Create Appender + + logger()->debug("Parsing logger: key '%1', value '%2'", rKey, rValue); + QStringList appenders = rValue.split(QLatin1Char(',')); + QStringListIterator i (appenders); + + // First entry is the level. There will be always one entry, even if the rValue is + // empty or does not contain a comma. + QString value = i.next().trimmed(); + if (!value.isEmpty()) + { + Level level; + if (value.compare(keyword_inherited,Qt::CaseInsensitive) == 0) + level = Level::NULL_INT; + else + level = OptionConverter::toLevel(value, Level::DEBUG_INT); + if (level == Level::NULL_INT && pLogger->name() == QString()) + logger()->warn("The root logger level cannot be set to NULL."); + else + { + pLogger->setLevel(level); + logger()->debug("Set level for logger '%1' to '%2'", + pLogger->name(), pLogger->level().toString()); + } + } + + pLogger->removeAllAppenders(); + while(i.hasNext()) + { + value = i.next().trimmed(); + if(value.isEmpty()) + continue; + LogObjectPtr p_appender = parseAppender(rProperties, value); + if (p_appender) + pLogger->addAppender(p_appender); + } + } + + + void PropertyConfigurator::setProperties(const Properties &rProperties, + const QString &rPrefix, + const QStringList &rExclusions, + QObject *pObject) + { + Q_ASSERT_X(!rPrefix.isEmpty(), "PropertyConfigurator::setProperties()", "rPrefix must not be empty."); + Q_ASSERT_X(pObject, "PropertyConfigurator::setProperties()", "pObject must not be null."); + + // Iterate through all entries: + // - Test for prefix to determine, if setting is for object + // - Skip empty property name + // - Skip property names in exclusion list + // - Set property on object + + logger()->debug("Setting properties for object of class '%1' from keys starting with '%2'", + QLatin1String(pObject->metaObject()->className()), + rPrefix); + + QStringList keys = rProperties.propertyNames(); + QString key; + Q_FOREACH(key, keys) + { + if (!key.startsWith(rPrefix)) + continue; + QString property = key.mid(rPrefix.length()); + if (property.isEmpty()) + continue; + QStringList split_property = property.split(QLatin1Char('.')); + if (rExclusions.contains(split_property.at(0), Qt::CaseInsensitive)) + continue; + QString value = OptionConverter::findAndSubst(rProperties, key); + Factory::setObjectProperty(pObject, property, value); + } + } + + + void PropertyConfigurator::startCaptureErrors() + { + Q_ASSERT_X(!mpConfigureErrors, "PropertyConfigurator::startCaptureErrors()", "mpConfigureErrors must be empty."); + + mpConfigureErrors = new ListAppender; + mpConfigureErrors->setName(QLatin1String("PropertyConfigurator")); + mpConfigureErrors->setConfiguratorList(true); + mpConfigureErrors->setThreshold(Level::ERROR_INT); + LogManager::logLogger()->addAppender(mpConfigureErrors); + } + + + bool PropertyConfigurator::stopCaptureErrors() + { + Q_ASSERT_X(mpConfigureErrors, "PropertyConfigurator::stopCaptureErrors()", "mpConfigureErrors must not be empty."); + + LogManager::logLogger()->removeAppender(mpConfigureErrors); + ConfiguratorHelper::setConfigureError(mpConfigureErrors->list()); + bool result = (mpConfigureErrors->list().count() == 0); + mpConfigureErrors = 0; + return result; + } + + + + /************************************************************************** + * Implementation: Operators, Helper + **************************************************************************/ + + +#ifndef QT_NO_DEBUG_STREAM + QDebug operator<<(QDebug debug, + const PropertyConfigurator &rPropertyConfigurator) + { + Q_UNUSED(rPropertyConfigurator); + debug.nospace() << "PropertyConfigurator(" + << ")"; + return debug.space(); + } +#endif + + + +} // namespace Logging diff --git a/src/log4qt/log4qt/propertyconfigurator.h b/src/log4qt/log4qt/propertyconfigurator.h new file mode 100644 index 0000000..eff3f55 --- /dev/null +++ b/src/log4qt/log4qt/propertyconfigurator.h @@ -0,0 +1,194 @@ +/****************************************************************************** + * + * package: Logging + * file: propertyconfigurator.h + * created: September 2007 + * author: Martin Heinrich + * + * + * Copyright 2007 Martin Heinrich + * + * 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. + * + ******************************************************************************/ + +#ifndef LOG4QT_PROPERTYCONFIGURATOR_H +#define LOG4QT_PROPERTYCONFIGURATOR_H + + +/****************************************************************************** + * Dependencies + ******************************************************************************/ + + +#include +#include "log4qt/helpers/logobjectptr.h" +#include "log4qt/log4qt.h" +#include "ukui-logmacros.h" + +/****************************************************************************** + * Declarations + ******************************************************************************/ + +class QSettings; + +namespace Log4Qt +{ + + class Appender; + class Layout; + class ListAppender; + class Logger; + class Properties; + class LoggerRepository; + + /*! + * \brief The class PropertyConfigurator allows the configuration of the + * package from a JAVA properties file. + * + * \note All the functions declared in this class are thread-safe. + */ + class LIBUKUILOG4QT_EXPORT PropertyConfigurator + { + public: + PropertyConfigurator(); + // virtual ~PropertyConfigurator(); // Use compiler default + private: + PropertyConfigurator(const PropertyConfigurator &rOther); // Not implemented + PropertyConfigurator &operator=(const PropertyConfigurator &rOther); // Not implemented + + public: + /*! + * \sa ConfiguratorHelper::configureError() + */ + bool doConfigure(const Properties &rProperties, + LoggerRepository *pLoggerRepository = 0); + + /*! + * \sa ConfiguratorHelper::configureError() + */ + bool doConfigure(const QString &rConfigFileName, + LoggerRepository *pLoggerRepository = 0); + + /*! + * Reads the configuration data from the QSettings object + * \a rSettings. + * + * \sa \ref Properties::load(const QSettings &) "Properties::load()", + * ConfiguratorHelper::configureError() + */ + bool doConfigure(const QSettings &rSettings, + LoggerRepository *pLoggerRepository = 0); + + // JAVA: void doConfigure(const QUrl &rUrl, LoggerRepository *pLoggerRepository); + + /*! + * \sa ConfiguratorHelper::configureError() + */ + static bool configure(const Properties &rProperties); + + /*! + * \sa ConfiguratorHelper::configureError() + */ + static bool configure(const QString &rConfigFilename); + + /*! + * Reads the configuration data from the QSettings object + * \a rSettings. + * + * \sa \ref doConfigure(const QSettings &, LoggerRepository *) "doConfigure()", + * \ref Properties::load(const QSettings &) "Properties::load()", + * ConfiguratorHelper::configureError() + */ + static bool configure(const QSettings &rSettings); + + // JAVA: static void configure(const QUrl &rUrl); + + /*! + * \sa ConfiguratorHelper::configureError(), + * ConfiguratorHelper::configurationFile() + */ + static bool configureAndWatch(const QString &rConfigFilename); + + private: + void configureFromFile(const QString &rConfigFileName, + LoggerRepository *pLoggerRepository); + void configureFromProperties(const Properties &rProperties, + LoggerRepository *pLoggerRepository); + void configureFromSettings(const QSettings &rSettings, + LoggerRepository *pLoggerRepository); + void configureGlobalSettings(const Properties &rProperties, + LoggerRepository *pLoggerRepository) const; + void configureNonRootElements(const Properties &rProperties, + LoggerRepository *pLoggerRepository); + void configureRootLogger(const Properties &rProperties, + LoggerRepository *pLoggerRepository); + void parseAdditivityForLogger(const Properties &rProperties, + Logger *pLogger, + const QString &rLog4jName) const; + LogObjectPtr parseAppender(const Properties &rProperties, + const QString &rName); + LogObjectPtr parseLayout(const Properties &rProperties, + const QString &rAppenderName); + void parseLogger(const Properties &rProperties, + Logger *pLogger, + const QString &rKey, + const QString &rValue); + void setProperties(const Properties &rProperties, + const QString &rPrefix, + const QStringList &rExclusions, + QObject *pObject); + void startCaptureErrors(); + bool stopCaptureErrors(); + + private: + LogObjectPtr mpConfigureErrors; + QHash< QString, LogObjectPtr > mAppenderRegistry; + }; + + /************************************************************************** + * Operators, Helper + **************************************************************************/ + +#ifndef QT_NO_DEBUG_STREAM + /*! + * \relates PropertyConfigurator + * + * Writes all object member variables to the given debug stream \a debug + * and returns the stream. + * + * + * %PropertyConfigurator() + * + * \sa QDebug + */ + QDebug operator<<(QDebug debug, + const PropertyConfigurator &rPropertyConfigurator); +#endif + + + /************************************************************************** + * Inline + **************************************************************************/ + + inline PropertyConfigurator::PropertyConfigurator() + {} + + +} // namspace Logging + + +// Q_DECLARE_TYPEINFO(Log4Qt::PropertyConfigurator, Q_COMPLEX_TYPE); // Use default + + +#endif // LOG4QT_PROPERTYCONFIGURATOR_H diff --git a/src/log4qt/log4qt/rollingfileappender.cpp b/src/log4qt/log4qt/rollingfileappender.cpp new file mode 100644 index 0000000..44f7bbe --- /dev/null +++ b/src/log4qt/log4qt/rollingfileappender.cpp @@ -0,0 +1,191 @@ +/****************************************************************************** + * + * package: Log4Qt + * file: rollingfileappender.cpp + * created: September 2007 + * author: Martin Heinrich + * + * + * Copyright 2007 Martin Heinrich + * + * 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. + * + ******************************************************************************/ + + + +/****************************************************************************** + * Dependencies + ******************************************************************************/ + + +#include "log4qt/rollingfileappender.h" + +#include +#include +#include +#include "log4qt/helpers/optionconverter.h" +#include "log4qt/layout.h" +#include "log4qt/loggingevent.h" + + + +namespace Log4Qt +{ + + + /************************************************************************ + Declarations + *************************************************************************/ + + + + /************************************************************************ + C helper functions + *************************************************************************/ + + + + /************************************************************************ + Class implementation: RollingFileAppender + *************************************************************************/ + + + RollingFileAppender::RollingFileAppender(QObject *pParent) : + FileAppender(pParent), + mMaxBackupIndex(1), + mMaximumFileSize(10*1024*1024) + { + } + + + RollingFileAppender::RollingFileAppender(Layout *pLayout, + const QString &rFileName, + QObject *pParent) : + FileAppender(pLayout, rFileName, pParent), + mMaxBackupIndex(1), + mMaximumFileSize(10*1024*1024) + { + } + + + RollingFileAppender::RollingFileAppender(Layout *pLayout, + const QString &rFileName, + bool append, + QObject *pParent) : + FileAppender(pLayout, rFileName, append, pParent), + mMaxBackupIndex(1), + mMaximumFileSize(10*1024*1024) + { + } + + + RollingFileAppender::~RollingFileAppender() + { + close(); + } + + + void RollingFileAppender::setMaxFileSize(const QString &rMaxFileSize) + { + bool ok; + qint64 max_file_size = OptionConverter::toFileSize(rMaxFileSize, &ok); + if (ok) + setMaximumFileSize(max_file_size); + } + + + void RollingFileAppender::append(const LoggingEvent &rEvent) + { + // Q_ASSERT_X(, "RollingFileAppender::append()", "Lock must be held by caller") + + FileAppender::append(rEvent); + if (writer()->device()->size() > this->mMaximumFileSize) + rollOver(); + } + + + void RollingFileAppender::rollOver() + { + // Q_ASSERT_X(, "RollingFileAppender::rollOver()", "Lock must be held by caller") + + logger()->debug("Rolling over with maxBackupIndex = %1", mMaxBackupIndex); + + closeFile(); + + QFile f; + f.setFileName(file() + QLatin1Char('.') + QString::number(mMaxBackupIndex)); + if (f.exists() && !removeFile(f)) + return; + + QString target_file_name; + int i; + for (i = mMaxBackupIndex - 1; i >=1; i--) + { + f.setFileName(file() + QLatin1Char('.') + QString::number(i)); + if (f.exists()) + { + target_file_name = file() + QLatin1Char('.') + QString::number(i + 1); + if (!renameFile(f, target_file_name)) + return; + } + } + + f.setFileName(file()); + target_file_name = file() + QLatin1String(".1"); + if (!renameFile(f, target_file_name)) + return; + + openFile(); + } + + +#ifndef QT_NO_DEBUG_STREAM + QDebug RollingFileAppender::debug(QDebug &rDebug) const + { + QString layout_name; + if (layout()) + layout_name = layout()->name(); + QString codec_name; + if (encoding()) + codec_name = QLatin1String(encoding()->name()); + + rDebug.nospace() << "RollingFileAppender(" + << "name:" << name() << " " + << "appendfile:" << appendFile() << " " + << "bufferedio:" << bufferedIo() << " " + << "encoding:" << codec_name << " " + << "file:" << file() << " " + << "filter:" << firstFilter() << " " + << "immediateflush:" << immediateFlush() << " " + << "isactive:" << isActive() << " " + << "isclosed:" << isClosed() << " " + << "layout:" << layout_name << " " + << "maxbackupindex:" << maxBackupIndex() << " " + << "maximumfilesize:" << maximumFileSize() << " " + << "referencecount:" << referenceCount() << " " + << "threshold:" << threshold().toString() << " " + << "writer:" << writer() + << ")"; + return rDebug.space(); + } +#endif // QT_NO_DEBUG_STREAM + + + + /************************************************************************** + * Implementation: Operators, Helper + **************************************************************************/ + + +} // namespace Log4Qt diff --git a/src/log4qt/log4qt/rollingfileappender.h b/src/log4qt/log4qt/rollingfileappender.h new file mode 100644 index 0000000..da008a9 --- /dev/null +++ b/src/log4qt/log4qt/rollingfileappender.h @@ -0,0 +1,164 @@ +/****************************************************************************** + * + * package: Log4Qt + * file: rollingfileappender.h + * created: September 2007 + * author: Martin Heinrich + * + * + * Copyright 2007 Martin Heinrich + * + * 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. + * + ******************************************************************************/ + +#ifndef LOG4QT_ROLINGFILEAPPENDER_H +#define LOG4QT_ROLINGFILEAPPENDER_H + + +/****************************************************************************** + * Dependencies + ******************************************************************************/ + +#include "log4qt/fileappender.h" +#include "ukui-logmacros.h" + +/****************************************************************************** + * Declarations + ******************************************************************************/ + +namespace Log4Qt +{ + + /*! + * \brief The class RollingFileAppender extends FileAppender to backup + * the log files when they reach a certain size. + * + * \note All the functions declared in this class are thread-safe. + * + * \note The ownership and lifetime of objects of this class are managed. + * See \ref Ownership "Object ownership" for more details. + */ + class LIBUKUILOG4QT_EXPORT RollingFileAppender : public FileAppender + { + Q_OBJECT + + /*! + * The property holds the maximum backup count used by the appender. + * + * The default is 1. + * + * \sa maxBackupIndex(), setMaxBackupIndex() + */ + Q_PROPERTY(int maxBackupIndex READ maxBackupIndex WRITE setMaxBackupIndex) + + /*! + * The property holds the maximum file size used by the appender. + * + * The default is 10 MB (10 * 1024 * 1024). + * + * \sa maximumFileSize(), setMaximumFileSize() + */ + Q_PROPERTY(qint64 maximumFileSize READ maximumFileSize WRITE setMaximumFileSize) + + /*! + * The property sets the maximum file size from a string value. + * + * \sa setMaxFileSize(), maximumFileSize() + */ + Q_PROPERTY(QString maxFileSize WRITE setMaxFileSize) + + public: + RollingFileAppender(QObject *pParent = 0); + RollingFileAppender(Layout *pLayout, + const QString &rFileName, + QObject *pParent = 0); + RollingFileAppender(Layout *pLayout, + const QString &rFileName, + bool append, + QObject *pParent = 0); + virtual ~RollingFileAppender(); + private: + RollingFileAppender(const RollingFileAppender &rOther); // Not implemented + RollingFileAppender &operator=(const RollingFileAppender &rOther); // Not implemented + + public: + int maxBackupIndex() const; + qint64 maximumFileSize() const; + void setMaxBackupIndex(int maxBackupIndex); + void setMaximumFileSize(qint64 maximumFileSize); + void setMaxFileSize(const QString &rMaxFileSize); + + protected: + virtual void append(const LoggingEvent &rEvent); + +#ifndef QT_NO_DEBUG_STREAM + /*! + * Writes all object member variables to the given debug stream + * \a rDebug and returns the stream. + * + * + * %RollingFileAppender(name:"RFA" appendfile:false bufferedio:true + * encoding:"" file:"/log.txt" filter: 0x0 + * immediateflush:true isactive:true + * isclosed:false layout:"TTCC" maxbackupindex:2 + * maximumfilesize:40 referencecount:1 + * threshold:"NULL" writer:0x4175af8) + * + * \sa QDebug, operator<<(QDebug debug, const LogObject &rLogObject) + */ + virtual QDebug debug(QDebug &rDebug) const; +#endif // QT_NO_DEBUG_STREAM + + private: + void rollOver(); + + private: + int mMaxBackupIndex; + qint64 mMaximumFileSize; + }; + + + /************************************************************************** + * Operators, Helper + **************************************************************************/ + + + /************************************************************************** + * Inline + **************************************************************************/ + + inline int RollingFileAppender::maxBackupIndex() const + { QMutexLocker locker(&mObjectGuard); + return mMaxBackupIndex; } + + inline qint64 RollingFileAppender::maximumFileSize() const + { QMutexLocker locker(&mObjectGuard); + return mMaximumFileSize; } + + inline void RollingFileAppender::setMaxBackupIndex(int maxBackupIndex) + { QMutexLocker locker(&mObjectGuard); + mMaxBackupIndex = maxBackupIndex; } + + inline void RollingFileAppender::setMaximumFileSize(qint64 maximumFileSize) + { QMutexLocker locker(&mObjectGuard); + mMaximumFileSize = maximumFileSize; } + + +} // namespace Log4Qt + + +// Q_DECLARE_TYPEINFO(Log4Qt::RollingFileAppender, Q_COMPLEX_TYPE); // Use default + + +#endif // LOG4QT_ROLINGFILEAPPENDER_H diff --git a/src/log4qt/log4qt/simplelayout.cpp b/src/log4qt/log4qt/simplelayout.cpp new file mode 100644 index 0000000..a7d5234 --- /dev/null +++ b/src/log4qt/log4qt/simplelayout.cpp @@ -0,0 +1,84 @@ +/****************************************************************************** + * + * package: Log4Qt + * file: simplelayout.cpp + * created: September 2007 + * author: Martin Heinrich + * + * + * Copyright 2007 Martin Heinrich + * + * 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. + * + ******************************************************************************/ + + + +/****************************************************************************** + * Dependencies + ******************************************************************************/ + + +#include "log4qt/simplelayout.h" + +#include +#include "log4qt/loggingevent.h" + + + +namespace Log4Qt +{ + + + /************************************************************************** + * Declarations + **************************************************************************/ + + + + /************************************************************************** + * C helper functions + **************************************************************************/ + + + + /************************************************************************** + * Class implementation: SimpleLayout + **************************************************************************/ + + + QString SimpleLayout::format(const LoggingEvent &rEvent) + { + return rEvent.level().toString() + QLatin1String(" - ") + rEvent.message() + Layout::endOfLine(); + } + + +#ifndef QT_NO_DEBUG_STREAM + QDebug SimpleLayout::debug(QDebug &rDebug) const + { + rDebug.nospace() << "SimpleLayout(" + << "name:" << name() << " " + << "referencecount:" << referenceCount() + << ")"; + return rDebug.space(); + } +#endif // QT_NO_DEBUG_STREAM + + + + /************************************************************************** + * Implementation: Operators, Helper + **************************************************************************/ + + +} // namespace Log4Qt diff --git a/src/log4qt/log4qt/simplelayout.h b/src/log4qt/log4qt/simplelayout.h new file mode 100644 index 0000000..233d188 --- /dev/null +++ b/src/log4qt/log4qt/simplelayout.h @@ -0,0 +1,102 @@ +/****************************************************************************** + * + * package: Log4Qt + * file: simplelayout.h + * created: September 2007 + * author: Martin Heinrich + * + * + * Copyright 2007 Martin Heinrich + * + * 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. + * + ******************************************************************************/ + +#ifndef LOG4QT_SIMPLELAYOUT_H +#define LOG4QT_SIMPLELAYOUT_H + + +/****************************************************************************** + * Dependencies + ******************************************************************************/ + +#include "log4qt/layout.h" +#include "ukui-logmacros.h" + +/****************************************************************************** + * Declarations + ******************************************************************************/ + + +namespace Log4Qt +{ + + /*! + * \brief The class SimpleLayout outputs the level and message of a logging + * event. + * + * \note The ownership and lifetime of objects of this class are managed. + * See \ref Ownership "Object ownership" for more details. + */ + class LIBUKUILOG4QT_EXPORT SimpleLayout : public Layout + { + Q_OBJECT + + public: + SimpleLayout(QObject *pParent = 0); + // virtual ~SimpleLayout(); // Use compiler default + private: + SimpleLayout(const SimpleLayout &rOther); // Not implemented + SimpleLayout &operator=(const SimpleLayout &rOther); // Not implemented + + public: + virtual QString format(const LoggingEvent &rEvent); + + protected: + +#ifndef QT_NO_DEBUG_STREAM + /*! + * Writes all object member variables to the given debug stream + * \a rDebug and returns the stream. + * + * + * %SimpleLayout(name:"SL" referencecount:1) + * + * \sa QDebug, operator<<(QDebug debug, const LogObject &rLogObject) + */ + virtual QDebug debug(QDebug &rDebug) const; +#endif // QT_NO_DEBUG_STREAM + }; + + + /************************************************************************** + * Operators, Helper + **************************************************************************/ + + + /************************************************************************** + * Inline + **************************************************************************/ + + inline SimpleLayout::SimpleLayout(QObject *pParent) : + Layout(pParent) + {} + + +} // namespace Log4Qt + + +// Q_DECLARE_TYPEINFO(Log4Qt::SimpleLayout, Q_COMPLEX_TYPE); // Use default + + +#endif // LOG4QT_SIMPLELAYOUT_H diff --git a/src/log4qt/log4qt/spi/filter.cpp b/src/log4qt/log4qt/spi/filter.cpp new file mode 100644 index 0000000..8f2d10e --- /dev/null +++ b/src/log4qt/log4qt/spi/filter.cpp @@ -0,0 +1,70 @@ +/****************************************************************************** + * + * package: Log4Qt + * file: filter.cpp + * created: September 2007 + * author: Martin Heinrich + * + * + * Copyright 2007 Martin Heinrich + * + * 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. + * + ******************************************************************************/ + + + +/****************************************************************************** + * Dependencies + ******************************************************************************/ + + +#include "log4qt/spi/filter.h" + +#include + + +namespace Log4Qt +{ + + + /************************************************************************** + * Declarations + **************************************************************************/ + + + + /************************************************************************** + * C helper functions + **************************************************************************/ + + + + /************************************************************************** + * Class implementation: Filter + **************************************************************************/ + + + void Filter::setNext(Filter *pFilter) + { + mpNext = pFilter; + } + + + + /************************************************************************** + * Implementation: Operators, Helper + **************************************************************************/ + + +} // namespace Log4Qt diff --git a/src/log4qt/log4qt/spi/filter.h b/src/log4qt/log4qt/spi/filter.h new file mode 100644 index 0000000..7b7e693 --- /dev/null +++ b/src/log4qt/log4qt/spi/filter.h @@ -0,0 +1,125 @@ +/****************************************************************************** + * + * package: Log4Qt + * file: filter.h + * created: September 2007 + * author: Martin Heinrich + * + * + * Copyright 2007 Martin Heinrich + * + * 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. + * + ******************************************************************************/ + +#ifndef LOG4QT_FILTER_H +#define LOG4QT_FILTER_H + + +/****************************************************************************** + * Dependencies + ******************************************************************************/ + +#include "log4qt/helpers/logobject.h" + +#include "log4qt/helpers/logobjectptr.h" +#include "log4qt/log4qt.h" +#include "ukui-logmacros.h" + + +/****************************************************************************** + * Declarations + ******************************************************************************/ + +namespace Log4Qt +{ + + class LoggingEvent; + + /*! + * \brief The class Filter is the base class for all filters. + * + * \note The ownership and lifetime of objects of this class are managed. + * See \ref Ownership "Object ownership" for more details. + */ + class LIBUKUILOG4QT_EXPORT Filter : public LogObject + { + Q_OBJECT + + /*! + * The property holds the next filter of this filter. + * + * The default is 0 for no next filter. + * + * \sa next(), setNext() + */ + Q_PROPERTY(Filter* next READ next WRITE setNext) + + public: + enum Decision + { + ACCEPT, + DENY, + NEUTRAL + }; + Q_ENUMS(Decision); + + public: + Filter(QObject *pObject = 0); + // Filter(const Filter &rOther); // Use compiler default + virtual ~Filter(); + // Filter &operator=(const Filter &rOther); // Use compiler default + + Filter* next() const; + void setNext(Filter *pFilter); + + virtual void activateOptions(); + virtual Decision decide(const LoggingEvent &rEvent) const = 0; + + private: + LogObjectPtr mpNext; + }; + + + /************************************************************************** + * Operators, Helper + **************************************************************************/ + + + /************************************************************************** + * Inline + **************************************************************************/ + + inline Filter::Filter(QObject *pObject) : + LogObject(pObject), + mpNext(0) + {} + + inline Filter::~Filter() + {} + + inline Filter* Filter::next() const + { return mpNext; } + + inline void Filter::activateOptions() + {} + + +} // namespace Log4Qt + + +// Q_DECLARE_TYPEINFO(Log4Qt::Filter, Q_COMPLEX_TYPE); // Use default +Q_DECLARE_TYPEINFO(Log4Qt::LogObjectPtr, Q_MOVABLE_TYPE); + + +#endif // LOG4QT_FILTER_H diff --git a/src/log4qt/log4qt/ttcclayout.cpp b/src/log4qt/log4qt/ttcclayout.cpp new file mode 100644 index 0000000..023ba11 --- /dev/null +++ b/src/log4qt/log4qt/ttcclayout.cpp @@ -0,0 +1,182 @@ +/****************************************************************************** + * + * package: Log4Qt + * file: ttcclayout.cpp + * created: September 2007 + * author: Martin Heinrich + * + * + * Copyright 2007 Martin Heinrich + * + * 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. + * + ******************************************************************************/ + + + +/****************************************************************************** + * Dependencies + ******************************************************************************/ + + +#include "log4qt/ttcclayout.h" + +#include +#include +#include "log4qt/helpers/datetime.h" +#include "log4qt/helpers/patternformatter.h" +#include "log4qt/logger.h" +#include "log4qt/loggingevent.h" + + + +namespace Log4Qt +{ + + + /************************************************************************** + * Declarations + **************************************************************************/ + + + + /************************************************************************** + * C helper functions + **************************************************************************/ + + + + /************************************************************************** + * Class implementation: TTCCLayout + **************************************************************************/ + + + TTCCLayout::TTCCLayout(QObject *pParent) : + Layout(pParent), + mCategoryPrefixing(true), + mContextPrinting(true), + mDateFormat(), + mThreadPrinting(true), + mpPatternFormatter(0) + { + setDateFormat(TIME_RELATIVE); + } + + + TTCCLayout::TTCCLayout(const QString &rDateFormat, + QObject *pParent) : + Layout(pParent), + mCategoryPrefixing(true), + mContextPrinting(true), + mDateFormat(rDateFormat), + mThreadPrinting(true), + mpPatternFormatter(0) + { + } + + + TTCCLayout::TTCCLayout(DateFormat dateFormat, + QObject *pParent) : + Layout(pParent), + mCategoryPrefixing(true), + mContextPrinting(true), + mDateFormat(), + mThreadPrinting(true), + mpPatternFormatter(0) + { + setDateFormat(dateFormat); + } + + + TTCCLayout::~TTCCLayout() + { + delete mpPatternFormatter; + } + + + void TTCCLayout::setDateFormat(DateFormat dateFormat) + { + switch (dateFormat) + { + case NONE: + setDateFormat(QLatin1String("NONE")); + break; + case ISO8601: + setDateFormat(QLatin1String("ISO8601")); + break; + case TIME_ABSOLUTE: + setDateFormat(QLatin1String("TIME_ABSOLUTE")); + break; + case DATE: + setDateFormat(QLatin1String("DATE")); + break; + case TIME_RELATIVE: + setDateFormat(QLatin1String("TIME_RELATIVE")); + break; + default: + Q_ASSERT_X(false, "TTCCLayout::setDateFormat", "Unkown DateFormat"); + setDateFormat(QString()); + } + } + + + QString TTCCLayout::format(const LoggingEvent &rEvent) + { + Q_ASSERT_X(mpPatternFormatter, "TTCCLayout::format()", "mpPatternConverter must not be null"); + + return mpPatternFormatter->format(rEvent); + } + + + void TTCCLayout::updatePatternFormatter() + { + QString pattern; + + pattern += QLatin1String("%d{") + mDateFormat + QLatin1String("}"); + if (mThreadPrinting) + pattern += QLatin1String(" [%t]"); + pattern += QLatin1String(" %-5p"); + if (mCategoryPrefixing) + pattern += QLatin1String(" %c"); + if (mContextPrinting) + pattern += QLatin1String(" %x"); + pattern += QLatin1String(" - %m%n"); + + delete mpPatternFormatter; + mpPatternFormatter = new PatternFormatter(pattern); + } + + +#ifndef QT_NO_DEBUG_STREAM + QDebug TTCCLayout::debug(QDebug &rDebug) const + { + rDebug.nospace() << "TTCCLayout(" + << "name:" << name() << " " + << "categoryprefixing:" << categoryPrefixing() << " " + << "contextprinting:" << contextPrinting() << " " + << "dateformat:" << dateFormat() << " " + << "referencecount:" << referenceCount() << " " + << "threadprinting:" << threadPrinting() + << ")"; + return rDebug.space(); + } +#endif // QT_NO_DEBUG_STREAM + + + + /************************************************************************** + * Implementation: Operators, Helper + **************************************************************************/ + + +} // namespace Log4Qt diff --git a/src/log4qt/log4qt/ttcclayout.h b/src/log4qt/log4qt/ttcclayout.h new file mode 100644 index 0000000..247cb9c --- /dev/null +++ b/src/log4qt/log4qt/ttcclayout.h @@ -0,0 +1,235 @@ +/****************************************************************************** + * + * package: Log4Qt + * file: ttcclayout.h + * created: September 2007 + * author: Martin Heinrich + * + * + * Copyright 2007 Martin Heinrich + * + * 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. + * + ******************************************************************************/ + +#ifndef LOG4QT_TTCCLAYOUT_H +#define LOG4QT_TTCCLAYOUT_H + + +/****************************************************************************** + * Dependencies + ******************************************************************************/ + +#include "log4qt/layout.h" +#include "ukui-logmacros.h" + +/****************************************************************************** + * Declarations + ******************************************************************************/ + +namespace Log4Qt +{ + + class LoggingEvent; + class PatternFormatter; + + /*! + * \brief The class TTCCLayout outputs the time, thread, logger and nested + * diagnostic context information of a logging event. + * + * \note The ownership and lifetime of objects of this class are managed. + * See \ref Ownership "Object ownership" for more details. + */ + class LIBUKUILOG4QT_EXPORT TTCCLayout : public Layout + { + Q_OBJECT + + /*! + * The property holds if the logger name is part of the formatted output. + * + * The default value is true for including the logger name. + * + * \sa categoryPrefixing(), setCategoryPrefixing() + */ + Q_PROPERTY(bool categoryPrefixing READ categoryPrefixing WRITE setCategoryPrefixing) + + /*! + * The property holds if the nested context information is part of the + * formatted output. + * + * The default value it true for including the nested context information. + * + * \sa contextPrinting(), setContextPrinting() + */ + Q_PROPERTY(bool contextPrinting READ contextPrinting WRITE setContextPrinting) + + /*! + * The property holds the date format used by the layout. + * + * The default date format is "TIME_RELATIVE". + * + * \sa dateFormat(), setDateFormat() + */ + Q_PROPERTY(QString dateFormat READ dateFormat WRITE setDateFormat) + + /*! + * The property holds if the thread name is part of the formatted output. + * + * The default value it true for including the thread name. + * + * \sa threadPrinting(), setThreadPrinting() + */ + Q_PROPERTY(bool threadPrinting READ threadPrinting WRITE setThreadPrinting) + + public: + /*! + * The enum DateFormat defines constants for date formats. + * + * \sa setDateFormat(DateFormat), DateTime::toString() + */ + enum DateFormat + { + /*! The none date format string is "NONE". */ + NONE, + /*! + * The iso8601 date format string is "ISO8601". The date will be + * formatted as yyyy-MM-dd hh:mm:ss.zzz. + */ + ISO8601, + /*! + * The absolute date format string is "TIME_ABSOLUTE". The date will be + * formatted as HH:mm:ss.zzz. + */ + TIME_ABSOLUTE, + /*! + * The date date format string is "DATE". The date will be formatted + * as MMM YYYY HH:mm:ss.zzzz. + */ + DATE, + /*! + * The relative date format string is "TIME_RELATIVE". The date will be + * formatted as milliseconds since start of the program. + */ + TIME_RELATIVE + }; + Q_ENUMS(DateFormat) + + TTCCLayout(QObject *pParent = 0); + TTCCLayout(const QString &rDateFormat, + QObject *pParent = 0); + + /*! + * Creates a TTCCLayout with the date formar value specified by + * the \a dateFormat constant and the parent \a pParent. + */ + TTCCLayout(DateFormat dateFormat, + QObject *pParent = 0); + + virtual ~TTCCLayout(); + private: + TTCCLayout(const TTCCLayout &rOther); // Not implemented + TTCCLayout &operator=(const TTCCLayout &rOther); // Not implemented + + public: + bool categoryPrefixing() const; + bool contextPrinting() const; + QString dateFormat() const; + // JAVA: bool ignoresThrowable() const; + bool threadPrinting() const; + void setCategoryPrefixing(bool categoryPrefixing); + void setContextPrinting(bool contextPrinting); + void setDateFormat(const QString &rDateFormat); + + /*! + * Sets the date format to the value specified by the \a dateFormat + * constant. + */ + void setDateFormat(DateFormat dateFormat); + + // JAVA: setIgnoresThrowable(bool ignoresThrowable); + void setThreadPrinting(bool threadPrinting); + virtual QString format(const LoggingEvent &rEvent); + + protected: +#ifndef QT_NO_DEBUG_STREAM + /*! + * Writes all object member variables to the given debug stream + * \a rDebug and returns the stream. + * + * + * %TTCCLayout(name:"TTCC" categoryprefixing:true + * contextprinting:true dateformat:"ISO8601" + * referencecount:1 threadprinting:true) + * + * \sa QDebug, operator<<(QDebug debug, const LogObject &rLogObject) + */ + virtual QDebug debug(QDebug &rDebug) const; +#endif // QT_NO_DEBUG_STREAM + + private: + void updatePatternFormatter(); + + private: + bool mCategoryPrefixing; + bool mContextPrinting; + QString mDateFormat; + bool mThreadPrinting; + PatternFormatter *mpPatternFormatter; + }; + + + /************************************************************************** + * Operators, Helper + **************************************************************************/ + + + /************************************************************************** + * Inline + **************************************************************************/ + + inline bool TTCCLayout::categoryPrefixing() const + { return mCategoryPrefixing; } + + inline bool TTCCLayout::contextPrinting() const + { return mContextPrinting; } + + inline QString TTCCLayout::dateFormat() const + { return mDateFormat; } + + inline bool TTCCLayout::threadPrinting() const + { return mThreadPrinting; } + + inline void TTCCLayout::setCategoryPrefixing(bool categoryPrefixing) + { mCategoryPrefixing = categoryPrefixing; + updatePatternFormatter(); } + + inline void TTCCLayout::setContextPrinting(bool contextPrinting) + { mContextPrinting = contextPrinting; + updatePatternFormatter(); } + + inline void TTCCLayout::setDateFormat(const QString &rDateFormat) + { mDateFormat = rDateFormat; + updatePatternFormatter(); } + + inline void TTCCLayout::setThreadPrinting(bool threadPrinting) + { mThreadPrinting = threadPrinting; + updatePatternFormatter(); } + + +} // namespace Log4Qt + + +// Q_DECLARE_TYPEINFO(Log4Qt::TTCCLayout, Q_COMPLEX_TYPE); // Use default + + +#endif // LOG4QT_TTCCLAYOUT_H diff --git a/src/log4qt/log4qt/varia/debugappender.cpp b/src/log4qt/log4qt/varia/debugappender.cpp new file mode 100644 index 0000000..d4d0bd2 --- /dev/null +++ b/src/log4qt/log4qt/varia/debugappender.cpp @@ -0,0 +1,127 @@ +/****************************************************************************** + * + * package: Log4Qt + * file: debugappender.cpp + * created: September 2007 + * author: Martin Heinrich + * + * + * Copyright 2007 Martin Heinrich + * + * 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. + * + ******************************************************************************/ + + + +/****************************************************************************** + * Dependencies + ******************************************************************************/ + + +#include "log4qt/varia/debugappender.h" + +#include +#include +#include "log4qt/layout.h" +#include "log4qt/loggingevent.h" +#if defined(Q_WS_WIN) || defined(Q_OS_WIN32) + #include +#endif + +namespace Log4Qt +{ + + + /************************************************************************** + * Declarations + **************************************************************************/ + + + + /************************************************************************** + * C helper functions + **************************************************************************/ + + + + /************************************************************************** + * Class implementation: DebugAppender + **************************************************************************/ + + + DebugAppender::DebugAppender(Layout *pLayout, + QObject *pParent) : + AppenderSkeleton(pParent) + { + setLayout(pLayout); + } + + + bool DebugAppender::requiresLayout() const + { + return true; + } + + + void DebugAppender::append(const LoggingEvent &rEvent) + { + // Q_ASSERT_X(, "DebugAppender::append()", "Lock must be held by caller"); + Q_ASSERT_X(layout(), "DebugAppender::append()", "Layout must not be null"); + + QString message(layout()->format(rEvent)); +#if defined(Q_OS_WIN32) || defined(Q_WS_WIN) + #if (QT_VERSION < 0x050000) + QT_WA({ + OutputDebugStringW(reinterpret_cast(message.utf16())); + }, { + OutputDebugStringA(message.toLocal8Bit().data()); + }); + #else + OutputDebugStringW(reinterpret_cast(message.utf16())); + #endif +#else + fprintf(stderr, "%s", message.toLocal8Bit().data()); + fflush(stderr); +#endif + } + + + + /************************************************************************** + * Implementation: Operators, Helper + **************************************************************************/ + + +#ifndef QT_NO_DEBUG_STREAM + QDebug DebugAppender::debug(QDebug &rDebug) const + { + QString layout_name; + if (layout()) + layout_name = layout()->name(); + + rDebug.nospace() << "DebugAppender(" + << "name:" << name() << " " + << "filter:" << firstFilter() << " " + << "isactive:" << isActive() << " " + << "isclosed:" << isClosed() << " " + << "layout:" << layout_name << " " + << "referencecount:" << referenceCount() << " " + << "threshold:" << threshold().toString() + << ")"; + return rDebug.space(); + } +#endif // QT_NO_DEBUG_STREAM + + +} // namspace Log4Qt diff --git a/src/log4qt/log4qt/varia/debugappender.h b/src/log4qt/log4qt/varia/debugappender.h new file mode 100644 index 0000000..e376ea7 --- /dev/null +++ b/src/log4qt/log4qt/varia/debugappender.h @@ -0,0 +1,134 @@ +/****************************************************************************** + * + * package: Log4Qt + * file: debugappender.h + * created: September 2007 + * author: Martin Heinrich + * + * + * Copyright 2007 Martin Heinrich + * + * 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. + * + ******************************************************************************/ + +#ifndef LOG4QT_DEBUGAPPENDER_H +#define LOG4QT_DEBUGAPPENDER_H + + +/****************************************************************************** + * Dependencies + ******************************************************************************/ + +#include "log4qt/appenderskeleton.h" +#include "ukui-logmacros.h" + + +/****************************************************************************** + * Declarations + ******************************************************************************/ + +namespace Log4Qt +{ + + /*! + * \brief The class DebugAppender appends logging events to the platform + * specific debug output. + * + * A DebugAppender appends to the Debugger on Windows and to stderr on all + * other systems. + * + * \note All the functions declared in this class are thread-safe. + * + * \note The ownership and lifetime of objects of this class are managed. + * See \ref Ownership "Object ownership" for more details. + */ + class LIBUKUILOG4QT_EXPORT DebugAppender : public AppenderSkeleton + { + Q_OBJECT + + public: + /*! + * Creates a DebugAppender. + */ + DebugAppender(QObject *pParent = 0); + + /*! + * Creates a DebugAppender with the specified layout \a pLayout + */ + DebugAppender(Layout *pLayout, + QObject *pParent = 0); + + // virtual ~DebugAppender(); // Use compiler default + private: + DebugAppender(const DebugAppender &rOther); // Not implemented + DebugAppender &operator=(const DebugAppender &rOther); // Not implemented + + public: + /*! + * The DebugAppended requires a layout. The function returns true. + * + * \sa setLayout() + */ + virtual bool requiresLayout() const; + + protected: + /*! + * Appends the specified logging event \a rEvent to the debug output. + * The output is formatted using the appender's layout. + * + * The method is called by the AppenderSkeleton::doAppend() after it + * the entry conditions have been tested and it has been found that the + * logging event needs to be appended. + * + * \sa setLayout(), AppenderSkeleton::doAppend(), checkEntryConditions() + */ + virtual void append(const LoggingEvent &rEvent); + +#ifndef QT_NO_DEBUG_STREAM + /*! + * Writes all object member variables to the given debug stream \a rDebug + * and returns the stream. + * + * + * %DebugAppender(name:"DA" filter:0x3bee6b8 isactive:true isclosed:false + * layout:"SL" referencecount:1 threshold:"NULL") + * + * \sa QDebug, operator<<(QDebug debug, const LogObject &rLogObject) + */ + virtual QDebug debug(QDebug &rDebug) const; +#endif // QT_NO_DEBUG_STREAM + }; + + + /************************************************************************** + * Operators, Helper + **************************************************************************/ + + + /************************************************************************** + * Inline + **************************************************************************/ + + inline DebugAppender::DebugAppender(QObject *pParent) : + AppenderSkeleton(pParent) + {} + + +} // namespace Log4Qt + + +// Q_DECLARE_TYPEINFO(Log4Qt::DebugAppender, Q_COMPLEX_TYPE); // Use default + + +#endif // LOG4QT_DEBUGAPPENDER_H diff --git a/src/log4qt/log4qt/varia/denyallfilter.cpp b/src/log4qt/log4qt/varia/denyallfilter.cpp new file mode 100644 index 0000000..31d8f64 --- /dev/null +++ b/src/log4qt/log4qt/varia/denyallfilter.cpp @@ -0,0 +1,77 @@ +/****************************************************************************** + * + * package: Log4Qt + * file: denyallfilter.cpp + * created: September 2007 + * author: Martin Heinrich + * + * + * Copyright 2007 Martin Heinrich + * + * 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. + * + ******************************************************************************/ + + + +/****************************************************************************** + * Dependencies + ******************************************************************************/ + + +#include "log4qt/varia/denyallfilter.h" + +#include + + +namespace Log4Qt +{ + + + /************************************************************************** + * Declarations + **************************************************************************/ + + + + /************************************************************************** + * C helper functions + **************************************************************************/ + + + + /************************************************************************** + * Class implementation: Filter + **************************************************************************/ + + +#ifndef QT_NO_DEBUG_STREAM + QDebug DenyAllFilter::debug(QDebug &rDebug) const + { + rDebug.nospace() << "DenyAllFilter(" + << "next:" << next() + << "referencecount:" << referenceCount() << " " + << ")"; + return rDebug.space(); + } +#endif // QT_NO_DEBUG_STREAM + + + + /************************************************************************** + * Implementation: Operators, Helper + **************************************************************************/ + + + +} // namespace Log4Qt diff --git a/src/log4qt/log4qt/varia/denyallfilter.h b/src/log4qt/log4qt/varia/denyallfilter.h new file mode 100644 index 0000000..dea0312 --- /dev/null +++ b/src/log4qt/log4qt/varia/denyallfilter.h @@ -0,0 +1,105 @@ +/****************************************************************************** + * + * package: Log4Qt + * file: denyallfilter.h + * created: September 2007 + * author: Martin Heinrich + * + * + * changes Feb 2009, Martin Heinrich + * - Fixed a compile error on VS 2008 by using Q_UNUSED(&rEvent) + * instead of Q_UNUSED(rEvent) + * + * + * Copyright 2007 - 2009 Martin Heinrich + * + * 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. + * + ******************************************************************************/ + +#ifndef LOG4QT_DENYALLFILTER_H +#define LOG4QT_DENYALLFILTER_H + + +/****************************************************************************** + * Dependencies + ******************************************************************************/ + +#include "log4qt/spi/filter.h" +#include "ukui-logmacros.h" + +/****************************************************************************** + * Declarations + ******************************************************************************/ + +namespace Log4Qt +{ + + /*! + * \brief The class DenyAllFilter drops all logging events + * + * \note The ownership and lifetime of objects of this class are managed. + * See \ref Ownership "Object ownership" for more details. + */ + class LIBUKUILOG4QT_EXPORT DenyAllFilter : public Filter + { + Q_OBJECT + + public: + DenyAllFilter(QObject *pParent = 0); + // DenyAllFilter(const DenyAllFilter &rOther); // Use compiler default + // virtual ~DenyAllFilter(); // Use compiler default + // DenyAllFilter &operator=(const DenyAllFilter &rOther); // Use compiler default + + virtual Decision decide(const LoggingEvent &rEvent) const; + + protected: +#ifndef QT_NO_DEBUG_STREAM + /*! + * Writes all object member variables to the given debug stream \a rDebug + * and returns the stream. + * + * + * %DenyAllFilter(next:QObject(0x0) referencecount:1 ) + * + * \sa QDebug, operator<<(QDebug debug, const LogObject &rLogObject) + */ + virtual QDebug debug(QDebug &rDebug) const; +#endif // QT_NO_DEBUG_STREAM + }; + + + /************************************************************************* + * Operators, Helper + *************************************************************************/ + + + /************************************************************************* + * Inline + *************************************************************************/ + + inline DenyAllFilter::DenyAllFilter(QObject *pParent) : + Filter(pParent) + {} + + inline Filter::Decision DenyAllFilter::decide(const LoggingEvent &rEvent) const + { Q_UNUSED(&rEvent); return Filter::DENY; } + + +} // namespace Log4Qt + + +// Q_DECLARE_TYPEINFO(Log4Qt::DenyAllFilter, Q_MOVABLE_TYPE); // Use default + + +#endif // LOG4QT_DENYALLFILTER_H diff --git a/src/log4qt/log4qt/varia/levelmatchfilter.cpp b/src/log4qt/log4qt/varia/levelmatchfilter.cpp new file mode 100644 index 0000000..32a3d84 --- /dev/null +++ b/src/log4qt/log4qt/varia/levelmatchfilter.cpp @@ -0,0 +1,100 @@ +/****************************************************************************** + * + * package: Log4Qt + * file: levelmatchfilter.cpp + * created: September 2007 + * author: Martin Heinrich + * + * + * Copyright 2007 Martin Heinrich + * + * 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. + * + ******************************************************************************/ + + + +/****************************************************************************** + * Dependencies + ******************************************************************************/ + + +#include "log4qt/varia/levelmatchfilter.h" + +#include +#include "log4qt/loggingevent.h" + + +namespace Log4Qt +{ + + + /************************************************************************** + * Declarations + **************************************************************************/ + + + + /************************************************************************** + * C helper functions + **************************************************************************/ + + + + /************************************************************************** + * Class implementation: Filter + **************************************************************************/ + + + LevelMatchFilter::LevelMatchFilter(QObject *pParent) : + Filter(pParent), + mAcceptOnMatch(true), + mLevelToMatch(Level::NULL_INT) + {} + + + Filter::Decision LevelMatchFilter::decide(const LoggingEvent &rEvent) const + { + if (mLevelToMatch == Level::NULL_INT || + rEvent.level() != mLevelToMatch) + return Filter::NEUTRAL; + + if (mAcceptOnMatch) + return Filter::ACCEPT; + else + return Filter::DENY; + } + + +#ifndef QT_NO_DEBUG_STREAM + QDebug LevelMatchFilter::debug(QDebug &rDebug) const + { + rDebug.nospace() << "LevelMatchFilter(" + << "acceptonmatch:" << mAcceptOnMatch << " " + << "leveltomatch:" << mLevelToMatch.toString() << " " + << "next:" << next() + << "referencecount:" << referenceCount() << " " + << ")"; + return rDebug.space(); + } +#endif // QT_NO_DEBUG_STREAM + + + + /************************************************************************** + * Implementation: Operators, Helper + **************************************************************************/ + + + +} // namespace Log4Qt diff --git a/src/log4qt/log4qt/varia/levelmatchfilter.h b/src/log4qt/log4qt/varia/levelmatchfilter.h new file mode 100644 index 0000000..fa22549 --- /dev/null +++ b/src/log4qt/log4qt/varia/levelmatchfilter.h @@ -0,0 +1,137 @@ +/****************************************************************************** + * + * package: Log4Qt + * file: levelmatchfilter.h + * created: September 2007 + * author: Martin Heinrich + * + * + * Copyright 2007 Martin Heinrich + * + * 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. + * + ******************************************************************************/ + +#ifndef LOG4QT_LEVELMATCHFILTER_H +#define LOG4QT_LEVELMATCHFILTER_H + + +/****************************************************************************** + * Dependencies + ******************************************************************************/ + +#include "log4qt/spi/filter.h" +#include "ukui-logmacros.h" +#include "log4qt/level.h" + + +/****************************************************************************** + * Declarations + ******************************************************************************/ + +namespace Log4Qt +{ + + /*! + * \brief The class LevelMatchFilter allows logging events with a specified + * level. + * + * \note The ownership and lifetime of objects of this class are managed. + * See \ref Ownership "Object ownership" for more details. + */ + class LIBUKUILOG4QT_EXPORT LevelMatchFilter : public Filter + { + Q_OBJECT + + /*! + * The property holds if an event is accpeted on a match. + * + * The default is true. + * + * \sa acceptOnMatch(), setAcceptOnMatch() + */ + Q_PROPERTY(bool acceptOnMatch READ acceptOnMatch WRITE setAcceptOnMatch) + + /*! + * The property holds the level to match for this filter. + * + * The default is Level::NULL_INT. + * + * \sa levelToMatch(), setLevelToMatch() + */ + Q_PROPERTY(Level levelToMatch READ levelToMatch WRITE setLevelToMatch) + + public: + LevelMatchFilter(QObject *pParent = 0); + // LevelMatchFilter(const LevelMatchFilter &rOther); // Use compiler default + // virtual ~LevelMatchFilter(); // Use compiler default + // LevelMatchFilter &operator=(const LevelMatchFilter &rOther); // Use compiler default + + bool acceptOnMatch() const; + Level levelToMatch() const; + void setAcceptOnMatch(bool accept); + void setLevelToMatch(Level level); + + virtual Decision decide(const LoggingEvent &rEvent) const; + + protected: +#ifndef QT_NO_DEBUG_STREAM + /*! + * Writes all object member variables to the given debug stream \a rDebug + * and returns the stream. + * + * + * %LevelMatchFilter(acceptonmatch:true leveltomatch:"WARN" + * next:Log4Qt::DenyAllFilter(0x3bce3a8) + * referencecount:1 ) + * + * \sa QDebug, operator<<(QDebug debug, const LogObject &rLogObject) + */ + virtual QDebug debug(QDebug &rDebug) const; +#endif // QT_NO_DEBUG_STREAM + + private: + bool mAcceptOnMatch; + Level mLevelToMatch; + }; + + + /************************************************************************** + * Operators, Helper + **************************************************************************/ + + + /************************************************************************** + * Inline + **************************************************************************/ + + inline bool LevelMatchFilter::acceptOnMatch() const + { return mAcceptOnMatch; } + + inline Level LevelMatchFilter::levelToMatch() const + { return mLevelToMatch; } + + inline void LevelMatchFilter::setAcceptOnMatch(bool accept) + { mAcceptOnMatch = accept; } + + inline void LevelMatchFilter::setLevelToMatch(Level level) + { mLevelToMatch = level; } + + +} // namespace Log4Qt + + +// Q_DECLARE_TYPEINFO(Log4Qt::LevelMatchFilter, Q_MOVABLE_TYPE); // Use default + + +#endif // LOG4QT_LEVELMATCHFILTER_H diff --git a/src/log4qt/log4qt/varia/levelrangefilter.cpp b/src/log4qt/log4qt/varia/levelrangefilter.cpp new file mode 100644 index 0000000..b219cd9 --- /dev/null +++ b/src/log4qt/log4qt/varia/levelrangefilter.cpp @@ -0,0 +1,104 @@ +/****************************************************************************** + * + * package: Log4Qt + * file: levelrangefilter.cpp + * created: September 2007 + * author: Martin Heinrich + * + * + * Copyright 2007 Martin Heinrich + * + * 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. + * + ******************************************************************************/ + + + +/****************************************************************************** + * Dependencies + ******************************************************************************/ + + +#include "log4qt/varia/levelrangefilter.h" + +#include +#include "log4qt/loggingevent.h" + + +namespace Log4Qt +{ + + +/****************************************************************************** + * Declarations + ******************************************************************************/ + + + +/****************************************************************************** + * C helper functions + ******************************************************************************/ + + + +/****************************************************************************** + * Class implementation: Filter + ******************************************************************************/ + + +LevelRangeFilter::LevelRangeFilter(QObject *pParent) : + Filter(pParent), + mAcceptOnMatch(true), + mLevelMin(Level::NULL_INT), + mLevelMax(Level::OFF_INT) +{} + + +Filter::Decision LevelRangeFilter::decide(const LoggingEvent &rEvent) const +{ + if (rEvent.level() < mLevelMin) + return Filter::DENY; + + if (rEvent.level() > mLevelMax) + return Filter::DENY; + + if (mAcceptOnMatch) + return Filter::ACCEPT; + else + return Filter::NEUTRAL; +} + + +#ifndef QT_NO_DEBUG_STREAM +QDebug LevelRangeFilter::debug(QDebug &rDebug) const +{ + rDebug.nospace() << "LevelRangeFilter(" + << "acceptonmatch:" << mAcceptOnMatch << " " + << "levelmin:" << mLevelMin.toString() << " " + << "levelmax:" << mLevelMax.toString() << " " + << "next:" << next() + << "referencecount:" << referenceCount() << " " + << ")"; + return rDebug.space(); +} +#endif // QT_NO_DEBUG_STREAM + + + +/****************************************************************************** + * Implementation: Operators, Helper + ******************************************************************************/ + + + +} // namespace Log4Qt diff --git a/src/log4qt/log4qt/varia/levelrangefilter.h b/src/log4qt/log4qt/varia/levelrangefilter.h new file mode 100644 index 0000000..90e8dd9 --- /dev/null +++ b/src/log4qt/log4qt/varia/levelrangefilter.h @@ -0,0 +1,153 @@ +/****************************************************************************** + * + * package: Log4Qt + * file: levelrangefilter.h + * created: September 2007 + * author: Martin Heinrich + * + * + * Copyright 2007 Martin Heinrich + * + * 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. + * + ******************************************************************************/ + +#ifndef LOG4QT_LEVELRANGEFILTER_H +#define LOG4QT_LEVELRANGEFILTER_H + + +/****************************************************************************** + * Dependencies + ******************************************************************************/ + +#include "log4qt/spi/filter.h" +#include "ukui-logmacros.h" +#include "log4qt/level.h" + + +/****************************************************************************** + * Declarations + ******************************************************************************/ + +namespace Log4Qt +{ + + /*! + * \brief The class LevelMatchFilter allows logging events with levels in a + * specified range. + * + * \note The ownership and lifetime of objects of this class are managed. + * See \ref Ownership "Object ownership" for more details. + */ + class LIBUKUILOG4QT_EXPORT LevelRangeFilter : public Filter + { + Q_OBJECT + + /*! + * The property holds if an event is accpeted on a match. + * + * The default is true. + * + * \sa acceptOnMatch(), acceptOnMatch() + */ + Q_PROPERTY(bool acceptOnMatch READ acceptOnMatch WRITE setAcceptOnMatch) + + /*! + * The property holds the maximum level of the range for this filter. + * + * The default is Level::OFF_INT. + * + * \sa levelMax(), setLevelMax() + */ + Q_PROPERTY(Level levelMax READ levelMax WRITE setLevelMax) + + /*! + * The property holds the minimum level of the range for this filter. + * + * The default is Level::NULL_INT. + * + * \sa levelMin(), setLevelMin() + */ + Q_PROPERTY(Level levelMin READ levelMin WRITE setLevelMin) + + public: + LevelRangeFilter(QObject *pParent = 0); + // LevelRangeFilter(const LevelRangeFilter &rOther); // Use compiler default + // virtual ~LevelRangeFilter(); // Use compiler default + // LevelRangeFilter &operator=(const LevelRangeFilter &rOther); // Use compiler default + + bool acceptOnMatch() const; + Level levelMax() const; + Level levelMin() const; + void setAcceptOnMatch(bool accept); + void setLevelMax(Level level); + void setLevelMin(Level level); + + virtual Decision decide(const LoggingEvent &rEvent) const; + + protected: + /*! + * Writes all object member variables to the given debug stream \a rDebug + * and returns the stream. + * + * + * %LevelRangeFilter(acceptonmatch:true levelmin:"ERROR" levelmax:"FATAL" + * next:Log4Qt::LevelMatchFilter(0x3bcd960) + * referencecount:1 ) + * + * \sa QDebug, operator<<(QDebug debug, const LogObject &rLogObject) + */ + virtual QDebug debug(QDebug &rDebug) const; + + private: + bool mAcceptOnMatch; + Level mLevelMin; + Level mLevelMax; + }; + + + /************************************************************************** + * Operators, Helper + **************************************************************************/ + + + /************************************************************************** + * Inline + **************************************************************************/ + + inline bool LevelRangeFilter::acceptOnMatch() const + { return mAcceptOnMatch; } + + inline Level LevelRangeFilter::levelMax() const + { return mLevelMax; } + + inline Level LevelRangeFilter::levelMin() const + { return mLevelMin; } + + inline void LevelRangeFilter::setAcceptOnMatch(bool accept) + { mAcceptOnMatch = accept; } + + inline void LevelRangeFilter::setLevelMax(Level level) + { mLevelMax = level; } + + inline void LevelRangeFilter::setLevelMin(Level level) + { mLevelMin = level; } + + +} // namespace Log4Qt + + +// Q_DECLARE_TYPEINFO(Log4Qt::LevelRangeFilter, Q_MOVABLE_TYPE); // Use default + + +#endif // LOG4QT_LEVELRANGEFILTER_H diff --git a/src/log4qt/log4qt/varia/listappender.cpp b/src/log4qt/log4qt/varia/listappender.cpp new file mode 100644 index 0000000..db20284 --- /dev/null +++ b/src/log4qt/log4qt/varia/listappender.cpp @@ -0,0 +1,153 @@ +/****************************************************************************** + * + * package: Log4Qt + * file: listappender.cpp + * created: September 2007 + * author: Martin Heinrich + * + * + * Copyright 2007 Martin Heinrich + * + * 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. + * + ******************************************************************************/ + + + +/****************************************************************************** + * Dependencies + ******************************************************************************/ + + +#include "log4qt/varia/listappender.h" + +#include + + + +namespace Log4Qt +{ + + + /************************************************************************** + * Declarations + **************************************************************************/ + + + + /************************************************************************** + * C helper functions + **************************************************************************/ + + + + /************************************************************************** + * Class implementation: ListAppender + **************************************************************************/ + + + ListAppender::ListAppender(QObject *pParent) : + AppenderSkeleton(pParent), + mConfiguratorList(false), + mList(), + mMaxCount(0) + { + } + + + ListAppender::~ListAppender() + { + } + + + QList ListAppender::list() const + { + QMutexLocker locker(&mObjectGuard); + + return mList; + } + + + void ListAppender::setMaxCount(int n) + { + QMutexLocker locker(&mObjectGuard); + + if (n < 0) + { + logger()->warn("Attempt to set maximum count for appender '%1' to %2. Using zero instead", name(), n); + n = 0; + } + mMaxCount = n; + ensureMaxCount(); + } + + + QList ListAppender::clearList() + { + QMutexLocker locker(&mObjectGuard); + + QList result = mList; + mList.clear(); + return result; + } + + + // bool ListAppender::requiresLayout() const; + + + void ListAppender::append(const LoggingEvent &rEvent) + { + // Q_ASSERT_X(, "ListAppender::append()", "Lock must be held by caller") + + if ((mMaxCount <= 0) || (mList.size() < mMaxCount)) + mList << rEvent; + } + + +#ifndef QT_NO_DEBUG_STREAM + QDebug ListAppender::debug(QDebug &rDebug) const + { + rDebug.nospace() << "ListAppender(" + << "name:" << name() << " " + << "count:" << list().count() << " " + << "filter:" << firstFilter() << " " + << "isactive:" << isActive() << " " + << "isclosed:" << isClosed() << " " + << "maxcount:" << maxCount() << " " + << "referencecount:" << referenceCount() << " " + << "threshold:" << threshold().toString() + << ")"; + return rDebug.space(); + } +#endif // QT_NO_DEBUG_STREAM + + + void ListAppender::ensureMaxCount() + { + // Q_ASSERT_X(, "ListAppender::ensureMaxCount()", "Lock must be held by caller") + + if (mMaxCount <= 0) + return; + + while (mList.size() > mMaxCount) + mList.removeFirst(); + } + + + + /************************************************************************** + * Implementation: Operators, Helper + **************************************************************************/ + + +} // namespace Log4Qt diff --git a/src/log4qt/log4qt/varia/listappender.h b/src/log4qt/log4qt/varia/listappender.h new file mode 100644 index 0000000..15d3159 --- /dev/null +++ b/src/log4qt/log4qt/varia/listappender.h @@ -0,0 +1,174 @@ +/****************************************************************************** + * + * package: Log4Qt + * file: listappender.h + * created: September 2007 + * author: Martin Heinrich + * + * + * Copyright 2007 Martin Heinrich + * + * 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. + * + ******************************************************************************/ + +#ifndef LOG4QT_LISTAPPENDER_H +#define LOG4QT_LISTAPPENDER_H + + +/****************************************************************************** + * Dependencies + ******************************************************************************/ + +#include "log4qt/appenderskeleton.h" +#include "ukui-logmacros.h" +#include +#include +#include "log4qt/loggingevent.h" + + +/****************************************************************************** + * Declarations + ******************************************************************************/ + +namespace Log4Qt +{ + + /*! + * \brief The class ListAppender appends logging events to a list for later + * processing. + * + * \note All the functions declared in this class are thread-safe. + * + * \note The ownership and lifetime of objects of this class are managed. + * See \ref Ownership "Object ownership" for more details. + */ + class LIBUKUILOG4QT_EXPORT ListAppender : public AppenderSkeleton + { + Q_OBJECT + + /*! + * The property holds, if the Appender is used by a configurator. + * + * The default value is false for not being a configurator list. + * + * \sa configuratorList(), setConfiguratorList() + */ + Q_PROPERTY(bool configuratorList READ configuratorList WRITE setConfiguratorList) + + /*! + * The property holds the maximum count used by the appender. + * + * The default maximum count is -1 for unlimited. + * + * \sa maxCount(), setMaxCount() + */ + Q_PROPERTY(int maxCount READ maxCount WRITE setMaxCount) + + public: + ListAppender(QObject *pParent = 0); + virtual ~ListAppender(); + private: + ListAppender(const ListAppender &rOther); // Not implemented + ListAppender &operator=(const ListAppender &rOther); // Not implemented + + public: + /*! + * Returns true, if the appender is used by a configurator. Otherweise it returns + * false. + * + * \sa setConfiguratorList() + */ + bool configuratorList() const; + + QList list() const; + int maxCount() const; + + /*! + * Sets that the appender is used by a configurator. If set to true, the appender + * will not be removed from a Logger when Logger::removeAllAppenders()is called. + * This way the appender can collect events raised during the configuration process. + * + * \sa configuratorList(), BasicConfigurator, PropertyConfigurator, + * ConfiguratorHelper::configureError() + */ + void setConfiguratorList(bool isConfiguratorList); + + void setMaxCount(int n); + + QList clearList(); + virtual bool requiresLayout() const; + + protected: + virtual void append(const LoggingEvent &rEvent); + +#ifndef QT_NO_DEBUG_STREAM + /*! + * Writes all object member variables to the given debug stream + * \a rDebug and returns the stream. + * + * + * %ListAppender(name:"LA" count:1 filter:0x41fa488 isactive:true + * isclosed:false maxcount:170 referencecount:1 + * threshold:"TRACE_SET") + * + * \sa QDebug, operator<<(QDebug debug, const LogObject &rLogObject) + */ + virtual QDebug debug(QDebug &rDebug) const; +#endif // QT_NO_DEBUG_STREAM + + /*! + * Ensures that the count of events is less or equal then the maxium + * count. If the list contains too many items, items are deleted from + * the begin of the list. + */ + void ensureMaxCount(); + + private: + volatile bool mConfiguratorList; + QList mList; + volatile int mMaxCount; + }; + + + /************************************************************************** + * Operators, Helper + **************************************************************************/ + + + /************************************************************************** + * Inline + **************************************************************************/ + + inline bool ListAppender::configuratorList() const + { // QMutexLocker locker(&mObjectGuard); // Read/Write of int is safe + return mConfiguratorList; } + + inline int ListAppender::maxCount() const + { return mMaxCount; } + + inline void ListAppender::setConfiguratorList(bool isConfiguratorList) + { // QMutexLocker locker(&mObjectGuard); // Read/Write of int is safe + mConfiguratorList = isConfiguratorList; } + + inline bool ListAppender::requiresLayout() const + { return false; } + + +} // namespace Log4Qt + + +// Q_DECLARE_TYPEINFO(Log4Qt::ListAppender, Q_COMPLEX_TYPE); // Use default + + +#endif // LOG4QT_LISTAPPENDER_H diff --git a/src/log4qt/log4qt/varia/nullappender.cpp b/src/log4qt/log4qt/varia/nullappender.cpp new file mode 100644 index 0000000..a12ebf2 --- /dev/null +++ b/src/log4qt/log4qt/varia/nullappender.cpp @@ -0,0 +1,104 @@ +/****************************************************************************** + * + * package: Log4Qt + * file: nullappender.cpp + * created: September 2007 + * author: Martin Heinrich + * + * + * Copyright 2007 Martin Heinrich + * + * 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. + * + ******************************************************************************/ + + + +/****************************************************************************** + * Dependencies + ******************************************************************************/ + + +#include "log4qt/varia/nullappender.h" + +#include +#include "log4qt/layout.h" +#include "log4qt/loggingevent.h" + + + +namespace Log4Qt +{ + + + /************************************************************************** + * Declarations + **************************************************************************/ + + + + /************************************************************************** + * C helper functions + **************************************************************************/ + + + + /************************************************************************** + * Class implementation: NullAppender + **************************************************************************/ + + + NullAppender::NullAppender(QObject *pParent) : + AppenderSkeleton(false, pParent) + { + } + + + NullAppender::~NullAppender() + { + close(); + } + + + void NullAppender::append(const LoggingEvent &rEvent) + { + Q_UNUSED(rEvent); + } + + +#ifndef QT_NO_DEBUG_STREAM + QDebug NullAppender::debug(QDebug &rDebug) const + { + QString layout_name; + if (layout()) + layout_name = layout()->name(); + + rDebug.nospace() << "NullAppender(" + << "name:" << name() << " " + << "isactive:" << isActive() << " " + << "isclosed:" << isClosed() << " " + << "layout:" << layout_name << " " + << "threshold:" << threshold().toString() << " " + << ")"; + return rDebug.space(); + } +#endif // QT_NO_DEBUG_STREAM + + + + /************************************************************************** + * Implementation: Operators, Helper + **************************************************************************/ + + +} // namespace Log4Qt diff --git a/src/log4qt/log4qt/varia/nullappender.h b/src/log4qt/log4qt/varia/nullappender.h new file mode 100644 index 0000000..8272174 --- /dev/null +++ b/src/log4qt/log4qt/varia/nullappender.h @@ -0,0 +1,102 @@ +/****************************************************************************** + * + * package: Log4Qt + * file: nullappender.h + * created: September 2007 + * author: Martin Heinrich + * + * + * Copyright 2007 Martin Heinrich + * + * 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. + * + ******************************************************************************/ + +#ifndef LOG4QT_NULLAPPENDER_H +#define LOG4QT_NULLAPPENDER_H + + +/****************************************************************************** + * Dependencies + ******************************************************************************/ + +#include "log4qt/appenderskeleton.h" +#include "ukui-logmacros.h" + +/****************************************************************************** + * Declarations + ******************************************************************************/ + +namespace Log4Qt +{ + +/*! + * \brief The class NullAppender ignores all requests to append. + * + * \note All the functions declared in this class are thread-safe. + * + * \note The ownership and lifetime of objects of this class are managed. See + * \ref Ownership "Object ownership" for more details. + */ +class LIBUKUILOG4QT_EXPORT NullAppender : public AppenderSkeleton +{ + Q_OBJECT + +public: + NullAppender(QObject *pParent = 0); + virtual ~NullAppender(); +private: + NullAppender(const NullAppender &rOther); // Not implemented + NullAppender &operator=(const NullAppender &rOther); // Not implemented + +public: + virtual bool requiresLayout() const; + +protected: + virtual void append(const LoggingEvent &rEvent); + +#ifndef QT_NO_DEBUG_STREAM + /*! + * Writes all object member variables to the given debug stream \a rDebug and + * returns the stream. + * + * + * %NullAppender() + * + * \sa QDebug, operator<<(QDebug debug, const LogObject &rLogObject) + */ + virtual QDebug debug(QDebug &rDebug) const; +#endif // QT_NO_DEBUG_STREAM +}; + + +/****************************************************************************** + * Operators, Helper + ******************************************************************************/ + + +/****************************************************************************** + * Inline + ******************************************************************************/ + +inline bool NullAppender::requiresLayout() const +{ return false; } + + +} // namespace Log4Qt + + +// Q_DECLARE_TYPEINFO(Log4Qt::NullAppender, Q_COMPLEX_TYPE); // Use default + + +#endif // LOG4QT_NULLAPPENDER_H diff --git a/src/log4qt/log4qt/varia/stringmatchfilter.cpp b/src/log4qt/log4qt/varia/stringmatchfilter.cpp new file mode 100644 index 0000000..e660b21 --- /dev/null +++ b/src/log4qt/log4qt/varia/stringmatchfilter.cpp @@ -0,0 +1,101 @@ +/****************************************************************************** + * + * package: Log4Qt + * file: stringmatchfilter.cpp + * created: September 2007 + * author: Martin Heinrich + * + * + * Copyright 2007 Martin Heinrich + * + * 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. + * + ******************************************************************************/ + + + +/****************************************************************************** + * Dependencies + ******************************************************************************/ + + +#include "log4qt/varia/stringmatchfilter.h" + +#include +#include "log4qt/loggingevent.h" + + +namespace Log4Qt +{ + + + /************************************************************************** + * Declarations + **************************************************************************/ + + + + /************************************************************************** + * C helper functions + **************************************************************************/ + + + + /************************************************************************** + * Class implementation: Filter + **************************************************************************/ + + + StringMatchFilter::StringMatchFilter(QObject *pParent) : + Filter(pParent), + mAcceptOnMatch(true), + mStringToMatch() + {} + + + Filter::Decision StringMatchFilter::decide(const LoggingEvent &rEvent) const + { + if (rEvent.message().isEmpty() || + mStringToMatch.isEmpty() || + rEvent.message().indexOf(mStringToMatch) < 0) + return Filter::NEUTRAL; + + if (mAcceptOnMatch) + return Filter::ACCEPT; + else + return Filter::DENY; + } + + +#ifndef QT_NO_DEBUG_STREAM + QDebug StringMatchFilter::debug(QDebug &rDebug) const + { + rDebug.nospace() << "StringMatchFilter(" + << "acceptonmatch:" << mAcceptOnMatch << " " + << "referencecount:" << referenceCount() << " " + << "stringtomatch:" << mStringToMatch << " " + << "next:" << next() + << ")"; + return rDebug.space(); + } +#endif // QT_NO_DEBUG_STREAM + + + + /************************************************************************** + * Implementation: Operators, Helper + **************************************************************************/ + + + +} // namespace Log4Qt diff --git a/src/log4qt/log4qt/varia/stringmatchfilter.h b/src/log4qt/log4qt/varia/stringmatchfilter.h new file mode 100644 index 0000000..db33e6a --- /dev/null +++ b/src/log4qt/log4qt/varia/stringmatchfilter.h @@ -0,0 +1,133 @@ +/****************************************************************************** + * + * package: Log4Qt + * file: stringmatchfilter.h + * created: September 2007 + * author: Martin Heinrich + * + * + * Copyright 2007 Martin Heinrich + * + * 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. + * + ******************************************************************************/ + +#ifndef LOG4QT_STRINGMATCHFILTER_H +#define LOG4QT_STRINGMATCHFILTER_H + + +/****************************************************************************** + * Dependencies + ******************************************************************************/ + +#include "log4qt/spi/filter.h" +#include "ukui-logmacros.h" + +/****************************************************************************** + * Declarations + ******************************************************************************/ + +namespace Log4Qt +{ + + /*! + * \brief The class StringMatchFilter allows logging events with a + * specified level. + * + * \note The ownership and lifetime of objects of this class are managed. + * See \ref Ownership "Object ownership" for more details. + */ + class LIBUKUILOG4QT_EXPORT StringMatchFilter : public Filter + { + Q_OBJECT + + /*! + * The property holds if an event is accpeted on a match. + * + * The default is true. + * + * \sa acceptOnMatch(), acceptOnMatch() + */ + Q_PROPERTY(bool acceptOnMatch READ acceptOnMatch WRITE setAcceptOnMatch) + + /*! + * The property holds the string to match for this filter. + * + * \sa stringToMatch(), setStringToMatch() + */ + Q_PROPERTY(QString stringToMatch READ stringToMatch WRITE setStringToMatch) + + public: + StringMatchFilter(QObject *pParent = 0); + // StringMatchFilter(const StringMatchFilter &rOther); // Use compiler default + // virtual ~StringMatchFilter(); // Use compiler default + // StringMatchFilter &operator=(const StringMatchFilter &rOther); // Use compiler default + + bool acceptOnMatch() const; + QString stringToMatch() const; + void setAcceptOnMatch(bool accept); + void setStringToMatch(const QString &rString); + + virtual Decision decide(const LoggingEvent &rEvent) const; + + protected: +#ifndef QT_NO_DEBUG_STREAM + /*! + * Writes all object member variables to the given debug stream + * \a rDebug and returns the stream. + * + * + * %StringMatchFilter(acceptonmatch:true referencecount:1 + * stringtomatch:"LDAP_STRONG_AUTH_REQUIRED" + * next:Log4Qt::LevelMatchFilter(0x3bdd960) ) + * + * \sa QDebug, operator<<(QDebug debug, const LogObject &rLogObject) + */ + virtual QDebug debug(QDebug &rDebug) const; +#endif // QT_NO_DEBUG_STREAM + + private: + bool mAcceptOnMatch; + QString mStringToMatch; + }; + + + /************************************************************************** + * Operators, Helper + **************************************************************************/ + + + /************************************************************************** + * Inline + **************************************************************************/ + + inline bool StringMatchFilter::acceptOnMatch() const + { return mAcceptOnMatch; } + + inline QString StringMatchFilter::stringToMatch() const + { return mStringToMatch; } + + inline void StringMatchFilter::setAcceptOnMatch(bool accept) + { mAcceptOnMatch = accept; } + + inline void StringMatchFilter::setStringToMatch(const QString &rString) + { mStringToMatch = rString; } + + +} // namespace Log4Qt + + +// Q_DECLARE_TYPEINFO(Log4Qt::StringMatchFilter, Q_MOVABLE_TYPE); // Use default + + +#endif // LOG4QT_STRINGMATCHFILTER_H diff --git a/src/log4qt/log4qt/writerappender.cpp b/src/log4qt/log4qt/writerappender.cpp new file mode 100644 index 0000000..25a633e --- /dev/null +++ b/src/log4qt/log4qt/writerappender.cpp @@ -0,0 +1,288 @@ +/****************************************************************************** + * + * package: Log4Qt + * file: writerappender.cpp + * created: September 2007 + * author: Martin Heinrich + * + * + * Copyright 2007 Martin Heinrich + * + * 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. + * + ******************************************************************************/ + + + +/****************************************************************************** + * Dependencies + ******************************************************************************/ + + +#include "log4qt/writerappender.h" + +#include +#include +#include "log4qt/layout.h" +#include "log4qt/loggingevent.h" + + + +namespace Log4Qt +{ + + + /************************************************************************** + * Declarations + **************************************************************************/ + + + + /************************************************************************** + * C helper functions + **************************************************************************/ + + + + /************************************************************************** + * Class implementation: WriterAppender + **************************************************************************/ + + + WriterAppender::WriterAppender(QObject *pParent) : + AppenderSkeleton(false, pParent), + mpEncoding(0), + mpWriter(0), + mImmediateFlush(true) + { + } + + + WriterAppender::WriterAppender(Layout *pLayout, + QObject *pParent) : + AppenderSkeleton(false, pParent), + mpEncoding(0), + mpWriter(0), + mImmediateFlush(true) + { + setLayout(pLayout); + } + + + WriterAppender::WriterAppender(Layout *pLayout, + QTextStream *pTextStream, + QObject *pParent) : + AppenderSkeleton(false, pParent), + mpEncoding(0), + mpWriter(pTextStream), + mImmediateFlush(true) + { + setLayout(pLayout); + } + + + WriterAppender::~WriterAppender() + { + close(); + } + + + void WriterAppender::setEncoding(QTextCodec *pEncoding) + { + QMutexLocker locker(&mObjectGuard); + + if (mpEncoding == pEncoding) + return; + + mpEncoding = pEncoding; + if (mpWriter) + { + if (mpEncoding) + mpWriter->setCodec(mpEncoding); + else + mpWriter->setCodec(QTextCodec::codecForLocale()); + } + } + + + void WriterAppender::setWriter(QTextStream *pTextStream) + { + QMutexLocker locker(&mObjectGuard); + + closeWriter(); + + mpWriter = pTextStream; + if (mpEncoding && mpWriter) + mpWriter->setCodec(mpEncoding); + writeHeader(); + } + + + void WriterAppender::activateOptions() + { + QMutexLocker locker(&mObjectGuard); + + if (!writer()) + { + LogError e = LOG4QT_QCLASS_ERROR(QT_TR_NOOP("Activation of Appender '%1' that requires writer and has no writer set"), + APPENDER_ACTIVATE_MISSING_WRITER_ERROR); + e << name(); + logger()->error(e); + return; + } + + AppenderSkeleton::activateOptions(); + } + + + void WriterAppender::close() + { + QMutexLocker locker(&mObjectGuard); + + if (isClosed()) + return; + + AppenderSkeleton::close(); + closeWriter(); + } + + + bool WriterAppender::requiresLayout() const + { + return true; + } + + + void WriterAppender::append(const LoggingEvent &rEvent) + { + // Q_ASSERT_X(, "WriterAppender::append()", "Lock must be held by caller"); + Q_ASSERT_X(layout(), "WriterAppender::append()", "Layout must not be null"); + + QString message(layout()->format(rEvent)); + + *mpWriter << message; + if (handleIoErrors()) + return; + + if (immediateFlush()) + { + mpWriter->flush(); + if (handleIoErrors()) + return; + } + } + + + bool WriterAppender::checkEntryConditions() const + { + // Q_ASSERT_X(, "WriterAppender::checkEntryConditions()", "Lock must be held by caller") + + if (!writer()) + { + LogError e = LOG4QT_QCLASS_ERROR(QT_TR_NOOP("Use of appender '%1' without a writer set"), + APPENDER_USE_MISSING_WRITER_ERROR); + e << name(); + logger()->error(e); + return false; + } + + return AppenderSkeleton::checkEntryConditions(); + } + + + void WriterAppender::closeWriter() + { + // Q_ASSERT_X(, "WriterAppender::closeWriter()", "Lock must be held by caller") + + if (!mpWriter) + return; + + writeFooter(); + mpWriter = 0; + } + + +#ifndef QT_NO_DEBUG_STREAM + QDebug WriterAppender::debug(QDebug &rDebug) const + { + QString layout_name; + if (layout()) + layout_name = layout()->name(); + QString codec_name; + if (encoding()) + codec_name = QLatin1String(encoding()->name()); + + rDebug.nospace() << "WriterAppender(" + << "name:" << name() << " " + << "encoding:" << codec_name << " " + << "filter:" << firstFilter() + << "immediateFlush:" << immediateFlush() + << "isactive:" << isActive() + << "isclosed:" << isClosed() + << "layout:" << layout_name + << "referencecount:" << referenceCount() << " " + << "threshold:" << threshold().toString() + << "writer:" << writer() + << ")"; + return rDebug.space(); + } +#endif // QT_NO_DEBUG_STREAM + + + bool WriterAppender::handleIoErrors() const + { + return false; + } + + + void WriterAppender::writeFooter() const + { + // Q_ASSERT_X(, "WriterAppender::writeFooter()", "Lock must be held by caller") + + if (!layout() || !mpWriter) + return; + + QString footer = layout()->footer(); + if (footer.isEmpty()) + return; + + *mpWriter << footer << Layout::endOfLine(); + if (handleIoErrors()) + return; + } + + + void WriterAppender::writeHeader() const + { + // Q_ASSERT_X(, "WriterAppender::writeHeader()", "Lock must be held by caller") + + if (!layout() || !mpWriter) + return; + + QString header = layout()->header(); + if (header.isEmpty()) + return; + + *mpWriter << header << Layout::endOfLine(); + if (handleIoErrors()) + return; + } + + + + /****************************************************************************** + * Implementation: Operators, Helper + ******************************************************************************/ + + +} // namespace Log4Qt diff --git a/src/log4qt/log4qt/writerappender.h b/src/log4qt/log4qt/writerappender.h new file mode 100644 index 0000000..ca2e087 --- /dev/null +++ b/src/log4qt/log4qt/writerappender.h @@ -0,0 +1,201 @@ +/****************************************************************************** + * + * package: Log4Qt + * file: writerappender.h + * created: September 2007 + * author: Martin Heinrich + * + * + * Copyright 2007 Martin Heinrich + * + * 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. + * + ******************************************************************************/ + +#ifndef LOG4QT_WRITERAPPENDER_H +#define LOG4QT_WRITERAPPENDER_H + + +/****************************************************************************** + * Dependencies + ******************************************************************************/ + +#include "log4qt/appenderskeleton.h" +#include "ukui-logmacros.h" + + +/****************************************************************************** + * Declarations + ******************************************************************************/ + +class QTextCodec; +class QTextStream; + +namespace Log4Qt +{ + + /*! + * \brief The class WriterAppender appends log events to a QTextStream. + * + * \note All the functions declared in this class are thread-safe. + *   + * \note The ownership and lifetime of objects of this class are managed. + * See \ref Ownership "Object ownership" for more details. + */ + class LIBUKUILOG4QT_EXPORT WriterAppender : public AppenderSkeleton + { + Q_OBJECT + + /*! + * The property holds the codec the appender uses. + * + * The default is null to use the codec the writer has set. + * + * \sa encoding(), setEncoding() + */ + Q_PROPERTY(QTextCodec* encoding READ encoding WRITE setEncoding) + + /*! + * The property holds the writer the appender uses. + * + * \sa writer(), setWriter() + */ + Q_PROPERTY(QTextStream* writer READ writer WRITE setWriter) + + /*! + * The property holds, if the writer flushes after all write operations. + * + * The default is true for flushing. + * + * \sa immediateFlush(), setImmediateFlush() + */ + Q_PROPERTY(bool immediateFlush READ immediateFlush WRITE setImmediateFlush) + + public: + WriterAppender(QObject *pParent = 0); + WriterAppender(Layout *pLayout, + QObject *pParent = 0); + WriterAppender(Layout *pLayout, + QTextStream *pTextStream, + QObject *pParent = 0); + virtual ~WriterAppender(); + private: + WriterAppender(const WriterAppender &rOther); // Not implemented + WriterAppender &operator=(const WriterAppender &rOther); // Not implemented + + public: + virtual bool requiresLayout() const; + QTextCodec *encoding() const; + bool immediateFlush() const; + QTextStream *writer() const; + + /*! + * Sets the codec used by the writer to \a pTextCoded. + * + * If a codec is set with setEncoding, it will overwrite the codec set + * in the text stream. A subsequent call with \a pTextCoded equals null + * will resets the codec to the default QTextCodec::codecForLocale(). + * + * \sa encoding(), QTextSream::setCodec(), QTextCodec::codecForLocale() + */ + void setEncoding(QTextCodec *pTextCodec); + void setImmediateFlush(bool immediateFlush); + void setWriter(QTextStream *pTextStream); + + virtual void activateOptions(); + virtual void close(); + + protected: + virtual void append(const LoggingEvent &rEvent); + + /*! + * Tests if all entry conditions for using append() in this class are + * met. + * + * If a conditions is not met, an error is logged and the function + * returns false. Otherwise the result of + * AppenderSkeleton::checkEntryConditions() is returned. + * + * The checked conditions are: + * - A writer has been set (APPENDER_USE_MISSING_WRITER_ERROR) + * + * The function is called as part of the checkEntryConditions() chain + * started by AppenderSkeleton::doAppend(). + * + * \sa AppenderSkeleton::doAppend(), + * AppenderSkeleton::checkEntryConditions() + */ + virtual bool checkEntryConditions() const; + + void closeWriter(); + +#ifndef QT_NO_DEBUG_STREAM + /*! + * Writes all object member variables to the given debug stream + * \a rDebug and returns the stream. + * + * + * %WriterAppender(name:"WA" encoding:"" immediateFlush:true + * isactive:false isclosed:false layout:"TTCC" + * referencecount:1 threshold:"NULL" + * writer:0x0) + * + * \sa QDebug, operator<<(QDebug debug, const LogObject &rLogObject ) + */ + virtual QDebug debug(QDebug &rDebug) const; +#endif // QT_NO_DEBUG_STREAM + + virtual bool handleIoErrors() const; + void writeFooter() const; + void writeHeader() const; + + private: + QTextCodec *mpEncoding; + QTextStream *mpWriter; + volatile bool mImmediateFlush; + }; + + + /************************************************************************** + * Operators, Helper + **************************************************************************/ + + + /************************************************************************** + * Inline + **************************************************************************/ + + inline QTextCodec *WriterAppender::encoding() const + { QMutexLocker locker(&mObjectGuard); + return mpEncoding; } + + inline bool WriterAppender::immediateFlush() const + { // QMutexLocker locker(&mObjectGuard); // Read/Write of int is safe + return mImmediateFlush; } + + inline QTextStream *WriterAppender::writer() const + { // QMutexLocker locker(&mObjectGuard); // Read/Write of int is safe + return mpWriter; } + + inline void WriterAppender::setImmediateFlush(bool immediateFlush) + { // QMutexLocker locker(&mObjectGuard); // Read/Write of int is safe + mImmediateFlush = immediateFlush; } + + +} // namespace Log4Qt + + +// Q_DECLARE_TYPEINFO(Log4Qt::WriterAppender, Q_COMPLEX_TYPE); // Use default + + +#endif // LOG4QT_WRITERAPPENDER_H diff --git a/src/log4qt/org.ukui.log4qt-test.gschema.xml b/src/log4qt/org.ukui.log4qt-test.gschema.xml new file mode 100644 index 0000000..6f23845 --- /dev/null +++ b/src/log4qt/org.ukui.log4qt-test.gschema.xml @@ -0,0 +1,39 @@ + + + + "true" + hook qt messages + Control if hook qt messages + + + "DEBUG,console,daily" + config rootLogger's level and appenders + config rootLogger's level and appenders:"level,appender" + + + ".yyyy-MM-dd" + daily log file pattern + set daily log file pattern format:one day + + + "%d{yyyy-MM-dd HH:mm:ss,zzz}(%-4r)[%t]|%-5p| - %m%n" + set log message's format + set log message's format + + + 3600 + set check log files delay time + set check log files delay time + + + 3 + set log files count + set log files count,unit s + + + 512 + set log files total size + set log files total size, unit M + + + diff --git a/src/log4qt/org.ukui.log4qt.gschema.xml b/src/log4qt/org.ukui.log4qt.gschema.xml new file mode 100644 index 0000000..c7bdb66 --- /dev/null +++ b/src/log4qt/org.ukui.log4qt.gschema.xml @@ -0,0 +1,49 @@ + + + + "true" + reset all log4j config + Control if reset all log4j config + + + "INFO" + config logLogger's output level + config logLogger's output level: DEBUG/INFO/WARN/ERROR + + + "true" + hook qt messages + Control if hook qt messages + + + "INFO,daily" + config rootLogger's level and appenders + config rootLogger's level and appenders:"level,appender" + + + ".yyyy-MM-dd" + daily log file pattern + set daily log file pattern format:one day + + + "%d{yyyy-MM-dd HH:mm:ss,zzz}(%-4r)[%t]|%-5p| - %m%n" + set log message's format + set log message's format + + + 3600 + set check log files delay time + set check log files delay time + + + 3 + set log files count + set log files count,unit s + + + 512 + set log files total size + set log files total size, unit M + + + diff --git a/src/log4qt/src/log4qt/appender.h b/src/log4qt/src/log4qt/appender.h new file mode 100644 index 0000000..81f6aa4 --- /dev/null +++ b/src/log4qt/src/log4qt/appender.h @@ -0,0 +1,135 @@ +/****************************************************************************** + * + * package: Log4Qt + * file: appender.h + * created: September 2007 + * author: Martin Heinrich + * + * + * Copyright 2007 Martin Heinrich + * + * 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. + * + ********************************************************************************/ + +#ifndef LOG4QT_APPENDER_H +#define LOG4QT_APPENDER_H + + +/****************************************************************************** + * Dependencies + ******************************************************************************/ + +#include "log4qt/helpers/logobject.h" + +#include "log4qt/helpers/logobjectptr.h" + +#include "log4qt/logger.h" + + +/****************************************************************************** + * Declarations + ******************************************************************************/ + +namespace Log4Qt +{ + + class Filter; + class Layout; + class LoggingEvent; + + /*! + * \brief The class Appender is the base class for all Appenders. + * + * To allow the whole hirarchy to be an ascendant of QObject Appender is + * not an interface. + * + * \note All the functions declared in this class are thread-safe. + * + * \note The ownership and lifetime of objects of this class are managed. + * See \ref Ownership "Object ownership" for more details. + */ + class Appender : public LogObject + { + Q_OBJECT + + /*! + * The property holds the Layout used by the Appender. + * + * \sa layout(), setLayout() + */ + Q_PROPERTY(Layout* layout READ layout WRITE setLayout) + + /*! + * The property holds the name of the Appender. + * + * \sa name(), setName() + */ + Q_PROPERTY(QString name READ name WRITE setName) + + /*! + * The property holds if the Appender requires a Layout or not. + * + * \sa requiresLayout(), setRequiresLayout() + */ + Q_PROPERTY(bool requiresLayout READ requiresLayout) + + public: + Appender(QObject *pParent = 0); + virtual ~Appender(); + private: + Appender(const Appender &rOther); // Not implemented + Appender &operator=(const Appender &rOther); // Not implemented + + public: + // JAVA: ErrorHandler* errorHandler(); + virtual Filter *filter() const = 0; + virtual QString name() const = 0; + virtual Layout *layout() const = 0; + virtual bool requiresLayout() const = 0; + // JAVA: void setErrorHandler(ErrorHandler *pErrorHandler); + virtual void setLayout(Layout *pLayout) = 0; + virtual void setName(const QString &rName) = 0; + + virtual void addFilter(Filter *pFilter) = 0; + virtual void clearFilters() = 0; + virtual void close() = 0; + virtual void doAppend(const LoggingEvent &rEvent) = 0; + }; + + + /************************************************************************** + * Operators, Helper + **************************************************************************/ + + + /************************************************************************** + * Inline + **************************************************************************/ + + inline Appender::Appender(QObject *pParent) : + LogObject(pParent) + {} + + inline Appender::~Appender() + {} + + +} // namespace Log4Qt + + +// Q_DECLARE_TYPEINFO(Log4Qt::Appender, Q_COMPLEX_TYPE); // Use default +Q_DECLARE_TYPEINFO(Log4Qt::LogObjectPtr, Q_MOVABLE_TYPE); + + +#endif // LOG4QT_APPENDER_H diff --git a/src/log4qt/src/log4qt/appenderskeleton.cpp b/src/log4qt/src/log4qt/appenderskeleton.cpp new file mode 100644 index 0000000..d9f784b --- /dev/null +++ b/src/log4qt/src/log4qt/appenderskeleton.cpp @@ -0,0 +1,261 @@ +/****************************************************************************** + * + * package: Log4Qt + * file: appenderskeleton.cpp + * created: September 2007 + * author: Martin Heinrich + * + * + * Copyright 2007 Martin Heinrich + * + * 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. + * + ******************************************************************************/ + + + +/****************************************************************************** + * Dependencies + ******************************************************************************/ + + +#include "log4qt/appenderskeleton.h" + +#include +#include "log4qt/layout.h" +#include "log4qt/loggingevent.h" +#include "log4qt/logmanager.h" +#include "log4qt/spi/filter.h" + + +namespace Log4Qt +{ + + + /************************************************************************** + * Declarations + ***************************************************************************/ + + + /*! + * \brief The class RecursionGuardLocker controls a boolean flag. + * + * It is a helper class to control a boolean flag. The class sets the flag + * on creation and resets it on destruction. + */ + class RecursionGuardLocker + { + public: + RecursionGuardLocker(bool *pGuard); + ~RecursionGuardLocker(); + private: + RecursionGuardLocker(const RecursionGuardLocker &rOther); // Not implemented + RecursionGuardLocker &operator=(const RecursionGuardLocker &rOther); // Not implemented + private: + bool *mpGuard; + }; + + + + /************************************************************************** + * C helper functions + **************************************************************************/ + + + + /************************************************************************** + * Class implementation: RecursionGuardLocker + ***************************************************************************/ + + + inline RecursionGuardLocker::RecursionGuardLocker(bool *pGuard) + { + Q_ASSERT_X(pGuard != 0, "RecursionGuardLocker::RecursionGuardLocker()", "Pointer to guard bool must not be null"); + + mpGuard = pGuard; + *mpGuard = true; + } + + + inline RecursionGuardLocker::~RecursionGuardLocker() + { + *mpGuard = false; + }; + + + + /************************************************************************** + * Class implementation: AppenderSkeleton + **************************************************************************/ + + + AppenderSkeleton::AppenderSkeleton(QObject *pParent) : + Appender(pParent), + mObjectGuard(QMutex::Recursive), // Recursive for doAppend() + mAppendRecursionGuard(false), + mIsActive(true), + mIsClosed(false), + mpLayout(0), + mThreshold(Level::NULL_INT), + mpHeadFilter(0), + mpTailFilter(0) + { + } + + + AppenderSkeleton::AppenderSkeleton(const bool isActive, + QObject *pParent) : + Appender(pParent), + mObjectGuard(QMutex::Recursive), // Recursive for doAppend() + mAppendRecursionGuard(false), + mIsActive(isActive), + mIsClosed(false), + mpLayout(0), + mThreshold(Level::NULL_INT), + mpHeadFilter(0), + mpTailFilter(0) + { + } + + + void AppenderSkeleton::activateOptions() + { + QMutexLocker locker(&mObjectGuard); + + if (requiresLayout() && !layout()) + { + LogError e = LOG4QT_QCLASS_ERROR(QT_TR_NOOP("Activation of appender '%1' that requires layout and has no layout set"), + APPENDER_ACTIVATE_MISSING_LAYOUT_ERROR); + e << name(); + logger()->error(e); + return; + } + mIsActive = true; + } + + + void AppenderSkeleton::addFilter(Filter *pFilter) + { + if(!pFilter) + { + logger()->warn("Adding null Filter to Appender '%1'", name()); + return; + } + + QMutexLocker locker(&mObjectGuard); + + mpTailFilter = pFilter; + if (mpHeadFilter) + mpHeadFilter->setNext(pFilter); + else + mpHeadFilter = pFilter; + } + + + void AppenderSkeleton::clearFilters() + { + QMutexLocker locker(&mObjectGuard); + + mpTailFilter = 0; + mpHeadFilter = 0; + } + + + void AppenderSkeleton::close() + { + QMutexLocker locker(&mObjectGuard); + + mIsClosed = true; + mIsActive = false; + } + + + void AppenderSkeleton::doAppend(const LoggingEvent &rEvent) + { + // The mutex serialises concurrent access from multiple threads. + // - e.g. two threads using the same logger + // - e.g. two threads using different logger with the same appender + // + // A call from the same thread will pass the mutex (QMutex::Recursive) + // and get to the recursion guard. The recursion guard blocks recursive + // invocation and prevents a possible endless loop. + // - e.g. an appender logs an error with a logger that uses it + + QMutexLocker locker(&mObjectGuard); + + if (mAppendRecursionGuard) + return; + + RecursionGuardLocker recursion_locker(&mAppendRecursionGuard); + + if (!checkEntryConditions()) + return; + if (!isAsSevereAsThreshold(rEvent.level())) + return; + + Filter *p_filter = mpHeadFilter; + while(p_filter) + { + Filter::Decision decision = p_filter->decide(rEvent); + if (decision == Filter::ACCEPT) + break; + else if (decision == Filter::DENY) + return; + else + p_filter = p_filter->next(); + } + + append(rEvent); + } + + + bool AppenderSkeleton::checkEntryConditions() const + { + // Q_ASSERT_X(, "WriterAppender::checkEntryConditions()", "Lock must be held by caller") + + if (!isActive()) + { + LogError e = LOG4QT_QCLASS_ERROR(QT_TR_NOOP("Use of non activated appender '%1'"), + APPENDER_NOT_ACTIVATED_ERROR); + e << name(); + logger()->error(e); + return false; + } + if (isClosed()) + { + LogError e = LOG4QT_QCLASS_ERROR(QT_TR_NOOP("Use of closed appender '%1'"), + APPENDER_CLOSED_ERROR); + e << name(); + logger()->error(e); + return false; + } + if (requiresLayout() && !layout()) + { + LogError e = LOG4QT_QCLASS_ERROR(QT_TR_NOOP("Use of appender '%1' that requires layout and has no layout set"), + APPENDER_USE_MISSING_LAYOUT_ERROR); + e << name(); + logger()->error(e); + return false; + } + + return true; + } + + + + /************************************************************************** + * Implementation: Operators, Helper + **************************************************************************/ + + +} // namespace Log4Qt diff --git a/src/log4qt/src/log4qt/appenderskeleton.h b/src/log4qt/src/log4qt/appenderskeleton.h new file mode 100644 index 0000000..6f252b3 --- /dev/null +++ b/src/log4qt/src/log4qt/appenderskeleton.h @@ -0,0 +1,225 @@ +/****************************************************************************** + * + * package: Log4Qt + * file: appenderskeleton.h + * created: September 2007 + * author: Martin Heinrich + * + * + * Copyright 2007 Martin Heinrich + * + * 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. + * + ******************************************************************************/ + +#ifndef LOG4QT_APPENDERSKELETON_H +#define LOG4QT_APPENDERSKELETON_H + + +/****************************************************************************** + * Dependencies +******************************************************************************/ + +#include "log4qt/appender.h" + +#include +#include "log4qt/helpers/logobjectptr.h" + + +/****************************************************************************** + * Declarations + ******************************************************************************/ + +namespace Log4Qt +{ + + class Filter; + class Layout; + class Logger; + class LoggingEvent; + + /*! + * \brief The class AppenderSkeleton implements general Appender functionality. + * + * \note All the functions declared in this class are thread-safe. + * + * \note The ownership and lifetime of objects of this class are managed. See + * \ref Ownership "Object ownership" for more details. + */ + class AppenderSkeleton : public Appender + { + Q_OBJECT + + /*! + * The property holds if the Appender has been activated. + * + * \sa isActive() + */ + Q_PROPERTY(bool isActive READ isActive) + + /*! + * The property holds if the Appender has been closed. + * + * \sa isClosed() + */ + Q_PROPERTY(bool isClosed READ isClosed) + + /*! + * The property holds the threshold level used by the Appender. + * + * \sa threshold(), setThreshold() + */ + Q_PROPERTY(Level threshold READ threshold WRITE setThreshold) + + public: + AppenderSkeleton(QObject *pParent = 0); + protected: + AppenderSkeleton(const bool isActive, + QObject *pParent = 0); + public: + // virtual ~AppenderSkeleton(); Use compiler default + private: + AppenderSkeleton(const AppenderSkeleton &rOther); // Not implemented + AppenderSkeleton &operator=(const AppenderSkeleton &rOther); // Not implemented + + public: + // JAVA: ErrorHandler* errorHandler(); + virtual Filter *filter() const; + virtual Layout *layout() const; + bool isActive() const; + bool isClosed() const; + virtual QString name() const; + Level threshold() const; + // JAVA: void setErrorHandler(ErrorHandler *pErrorHandler); + virtual void setLayout(Layout *pLayout); + virtual void setName(const QString &rName); + void setThreshold(Level level); + + virtual void activateOptions(); + virtual void addFilter(Filter *pFilter); + virtual void clearFilters(); + virtual void close(); + + /*! + * Performs checks and delegates the actuall appending to the subclass + * specific append() function. + * + * \sa append(), checkEntryConditions(), isAsSevereAsThreshold(), Filter + */ + virtual void doAppend(const LoggingEvent &rEvent); + + // JAVA: void finalize(); + Filter* firstFilter() const; + bool isAsSevereAsThreshold(Level level) const; + + protected: + virtual void append(const LoggingEvent &rEvent) = 0; + + /*! + * Tests if all entry conditions for using append() in this class are + * met. + * + * If a conditions is not met, an error is logged and the function + * returns false. + * + * The checked conditions are: + * - That the appender has been activated (APPENDER_NOT_ACTIVATED_ERROR) + * - That the appender was not closed (APPENDER_CLOSED_ERROR) + * - That the appender has a layout set, if it requires one + * (logging_error(APPENDER_USE_MISSING_LAYOUT_ERROR) + * + * The function is called as part of the checkEntryConditions() chain + * started by doAppend(). The doAppend() function calls the subclass + * specific checkEntryConditions() function. The function checks the + * class specific conditions and calls checkEntryConditions() of + * it's parent class. The last function called is + * AppenderSkeleton::checkEntryConditions(). + * + * \sa doAppend() + */ + virtual bool checkEntryConditions() const; + + protected: + mutable QMutex mObjectGuard; + private: + bool mAppendRecursionGuard; + volatile bool mIsActive; + volatile bool mIsClosed; + LogObjectPtr mpLayout; + Level mThreshold; + LogObjectPtr mpHeadFilter; + LogObjectPtr mpTailFilter; + }; + + + /************************************************************************** + * Operators, Helper + **************************************************************************/ + + + /************************************************************************** + * Inline + **************************************************************************/ + + inline Filter *AppenderSkeleton::filter() const + { QMutexLocker locker(&mObjectGuard); + return mpHeadFilter; } + + inline Layout *AppenderSkeleton::layout() const + { QMutexLocker locker(&mObjectGuard); + return mpLayout; } + + inline QString AppenderSkeleton::name() const + { QMutexLocker locker(&mObjectGuard); + return objectName(); } + + inline Level AppenderSkeleton::threshold() const + { // QMutexLocker locker(&mObjectGuard); // Level is threadsafe + return mThreshold; } + + inline void AppenderSkeleton::setLayout(Layout *pLayout) + { QMutexLocker locker(&mObjectGuard); + mpLayout = pLayout; } + + inline void AppenderSkeleton::setName(const QString &rName) + { QMutexLocker locker(&mObjectGuard); + setObjectName(rName); } + + inline void AppenderSkeleton::setThreshold(Level level) + { // QMutexLocker locker(&mObjectGuard); // Level is threadsafe + mThreshold = level; } + + inline bool AppenderSkeleton::isActive() const + { // QMutexLocker locker(&mObjectGuard); // Read/Write of int is safe + return mIsActive; } + + inline bool AppenderSkeleton::isClosed() const + { // QMutexLocker locker(&mObjectGuard); // Read/Write of int is safe + return mIsClosed; } + + inline Filter *AppenderSkeleton::firstFilter() const + { QMutexLocker locker(&mObjectGuard); + return filter(); } + + inline bool AppenderSkeleton::isAsSevereAsThreshold(Level level) const + { // QMutexLocker locker(&mObjectGuard); // Level is threadsafe + return (mThreshold <= level); } + + +} // namespace Log4Qt + + +// Q_DECLARE_TYPEINFO(Log4Qt::AppenderSkeleton, Q_COMPLEX_TYPE); // Use default + + +#endif // LOG4QT_APPENDERSKELETON_H diff --git a/src/log4qt/src/log4qt/basicconfigurator.cpp b/src/log4qt/src/log4qt/basicconfigurator.cpp new file mode 100644 index 0000000..280b88d --- /dev/null +++ b/src/log4qt/src/log4qt/basicconfigurator.cpp @@ -0,0 +1,107 @@ +/****************************************************************************** + * + * package: Log4Qt + * file: basicconfigurator.cpp + * created: September 2007 + * author: Martin Heinrich + * + * + * Copyright 2007 Martin Heinrich + * + * 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. + * + ******************************************************************************/ + + + +/****************************************************************************** + * Dependencies + ******************************************************************************/ + + +#include "log4qt/basicconfigurator.h" + +#include +#include +#include +#include "log4qt/consoleappender.h" +#include "log4qt/helpers/configuratorhelper.h" +#include "log4qt/helpers/logobjectptr.h" +#include "log4qt/logmanager.h" +#include "log4qt/patternlayout.h" +#include "log4qt/varia/listappender.h" + + + +namespace Log4Qt +{ + + + /************************************************************************** + * Declarations + **************************************************************************/ + + + + /************************************************************************** + * C helper functions + **************************************************************************/ + + + + /************************************************************************** + * Class implementation: BasicConfigurator + **************************************************************************/ + + + bool BasicConfigurator::configure() + { + LogObjectPtr list = new ListAppender; + list->setName(QLatin1String("BasicConfigurator")); + list->setConfiguratorList(true); + list->setThreshold(Level::ERROR_INT); + LogManager::logLogger()->addAppender(list); + + PatternLayout *p_layout = new PatternLayout(PatternLayout::TTCC_CONVERSION_PATTERN); + p_layout->setName(QLatin1String("BasicConfigurator TTCC")); + p_layout->activateOptions(); + ConsoleAppender *p_appender = new ConsoleAppender(p_layout, ConsoleAppender::STDOUT_TARGET); + p_appender->setName(QLatin1String("BasicConfigurator stdout")); + p_appender->activateOptions(); + LogManager::rootLogger()->addAppender(p_appender); + + LogManager::logLogger()->removeAppender(list); + ConfiguratorHelper::setConfigureError(list->list()); + return (list->list().count() == 0); + } + + + void BasicConfigurator::configure(Appender *pAppender) + { + LogManager::rootLogger()->addAppender(pAppender); + } + + + void BasicConfigurator::resetConfiguration() + { + LogManager::resetConfiguration(); + } + + + + /************************************************************************** + * Implementation: Operators, Helper + **************************************************************************/ + + +} // namespace Log4Qt diff --git a/src/log4qt/src/log4qt/basicconfigurator.h b/src/log4qt/src/log4qt/basicconfigurator.h new file mode 100644 index 0000000..c301501 --- /dev/null +++ b/src/log4qt/src/log4qt/basicconfigurator.h @@ -0,0 +1,84 @@ +/****************************************************************************** + * + * package: Log4Qt + * file: basicconfigurator.h + * created: September 2007 + * author: Martin Heinrich + * + * + * Copyright 2007 Martin Heinrich + * + * 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. + * + ******************************************************************************/ + +#ifndef LOG4QT_BASICCONFIGURATOR_H +#define LOG4QT_BASICCONFIGURATOR_H + + +/****************************************************************************** + * Dependencies + ******************************************************************************/ + + +#include +#include "log4qt/log4qt.h" + + +/****************************************************************************** + * Declarations + ******************************************************************************/ + +namespace Log4Qt +{ + + class Appender; + + /*! + * \brief The class BasicConfigurator provides a simple package + * configuration. + * + * \note All the functions declared in this class are thread-safe. + */ + class BasicConfigurator + { + private: + BasicConfigurator(); // Not implemented + // BasicConfigurator(const BasicConfigurator &rOther); // Use compiler default + // virtual ~BasicConfigurator(); // Use compiler default + // BasicConfigurator &operator=(const BasicConfigurator &rOther); // Use compiler default + + public: + static bool configure(); + static void configure(Appender *pAppender); + static void resetConfiguration(); + }; + + + /************************************************************************** + * Operators, Helper + **************************************************************************/ + + + /************************************************************************** + * Inline + **************************************************************************/ + + +} // namspace Log4Qt + + +// Q_DECLARE_TYPEINFO(Log4Qt::BasicConfigurator, Q_MOVABLE_TYPE); // Use default + + +#endif // LOG4QT_BASICCONFIGURATOR_H diff --git a/src/log4qt/src/log4qt/consoleappender.cpp b/src/log4qt/src/log4qt/consoleappender.cpp new file mode 100644 index 0000000..1b4fe03 --- /dev/null +++ b/src/log4qt/src/log4qt/consoleappender.cpp @@ -0,0 +1,198 @@ +/****************************************************************************** + * + * package: Log4Qt + * file: consoleappender.cpp + * created: September 2007 + * author: Martin Heinrich + * + * + * Copyright 2007 Martin Heinrich + * + * 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. + * + ******************************************************************************/ + + + +/****************************************************************************** + * Dependencies + ******************************************************************************/ + + +#include "log4qt/consoleappender.h" + +#include +#include +#include "log4qt/helpers/optionconverter.h" +#include "log4qt/layout.h" +#include "log4qt/loggingevent.h" + + + +namespace Log4Qt +{ + + + /************************************************************************** + * Declarations + **************************************************************************/ + + + + /************************************************************************** + * C helper functions + **************************************************************************/ + + + + /************************************************************************** + * Class implementation: ConsoleAppender + **************************************************************************/ + + + ConsoleAppender::ConsoleAppender(QObject *pParent) : + WriterAppender(pParent), + mTarget(STDOUT_TARGET), + mpTextStream(0) + { + } + + + ConsoleAppender::ConsoleAppender(Layout *pLayout, + QObject *pParent) : + WriterAppender(pLayout, pParent), + mTarget(STDOUT_TARGET), + mpTextStream(0) + { + } + + + ConsoleAppender::ConsoleAppender(Layout *pLayout, + const QString &rTarget, + QObject *pParent) : + WriterAppender(pLayout, pParent), + mTarget(STDOUT_TARGET), + mpTextStream(0) + { + setTarget(rTarget); + } + + + ConsoleAppender::ConsoleAppender(Layout *pLayout, + Target target, + QObject *pParent) : + WriterAppender(pLayout, pParent), + mTarget(target), + mpTextStream(0) + { + } + + + ConsoleAppender::~ConsoleAppender() + { + close(); + } + + + QString ConsoleAppender::target() const + { + // QMutexLocker locker(&mObjectGuard); // Read/Write of int is safe + + if (mTarget == STDOUT_TARGET) + return QLatin1String("STDOUT_TARGET"); + else + return QLatin1String("STDERR_TARGET"); + } + + + void ConsoleAppender::setTarget(const QString &rTarget) + { + bool ok; + Target target = (Target)OptionConverter::toTarget(rTarget, &ok); + if (ok) + setTarget(target); + } + + + void ConsoleAppender::activateOptions() + { + QMutexLocker locker(&mObjectGuard); + + closeStream(); + + if (mTarget == STDOUT_TARGET) + mpTextStream = new QTextStream(stdout); + else + mpTextStream = new QTextStream(stderr); + setWriter(mpTextStream); + + WriterAppender::activateOptions(); + } + + + void ConsoleAppender::close() + { + QMutexLocker locker(&mObjectGuard); + + if (isClosed()) + return; + + WriterAppender::close(); + closeStream(); + } + + + void ConsoleAppender::closeStream() + { + // Q_ASSERT_X(, "ConsoleAppender::closeStream()", "Lock must be held by caller") + + setWriter(0); + delete mpTextStream; + mpTextStream = 0; + } + + +#ifndef QT_NO_DEBUG_STREAM + QDebug ConsoleAppender::debug(QDebug &rDebug) const + { + QString layout_name; + if (layout()) + layout_name = layout()->name(); + QString target; + if (mTarget == STDOUT_TARGET) + target = QLatin1String("STDOUT"); + else + target = QLatin1String("STDERR"); + + rDebug.nospace() << "ConsoleAppender(" + << "name:" << name() << " " + << "filter:" << firstFilter() << " " + << "isactive:" << isActive() << " " + << "isclosed:" << isClosed() << " " + << "layout:" << layout_name << " " + << "target:" << target << " " + << "referencecount:" << referenceCount() << " " + << "threshold:" << threshold().toString() + << ")"; + return rDebug.space(); + } +#endif // QT_NO_DEBUG_STREAM + + + + /****************************************************************************** + * Implementation: Operators, Helper + ******************************************************************************/ + + +} // namespace Log4Qt diff --git a/src/log4qt/src/log4qt/consoleappender.h b/src/log4qt/src/log4qt/consoleappender.h new file mode 100644 index 0000000..466015d --- /dev/null +++ b/src/log4qt/src/log4qt/consoleappender.h @@ -0,0 +1,160 @@ +/****************************************************************************** + * + * package: Log4Qt + * file: consoleappender.h + * created: September 2007 + * author: Martin Heinrich + * + * + * Copyright 2007 Martin Heinrich + * + * 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. + * + ******************************************************************************/ + +#ifndef LOG4QT_CONSOLEAPPENDER_H +#define LOG4QT_CONSOLEAPPENDER_H + + +/****************************************************************************** + * Dependencies + ******************************************************************************/ + +#include "log4qt/writerappender.h" + + +/****************************************************************************** + * Declarations + ******************************************************************************/ + +class QFile; +class QTextStream; + +namespace Log4Qt +{ + + /*! + * \brief The class ConsoleAppender appends to stdout or stderr. + * + * \note All the functions declared in this class are thread-safe. + * + * \note The ownership and lifetime of objects of this class are managed. + * See \ref Ownership "Object ownership" for more details. + */ + class ConsoleAppender : public WriterAppender + { + Q_OBJECT + + /*! + * The property holds the target used by the appender. + * + * The default is STDOUT_TARGET for the standard output. + * + * \sa Target, target(), setTarget() + */ + Q_PROPERTY(QString target READ target WRITE setTarget) + + public: + /*! + * The enum defines the possible output targets + * + * \sa target(), setTarget() + */ + enum Target { + /*! The output target is standard out. */ + STDOUT_TARGET, + /*! The output target is standard error. */ + STDERR_TARGET + }; + Q_ENUMS(Target) + + ConsoleAppender(QObject *pParent = 0); + ConsoleAppender(Layout *pLayout, + QObject *pParent = 0); + ConsoleAppender(Layout *pLayout, + const QString &rTarget, + QObject *pParent = 0); + + /*! + * Creates a ConsoleAppender with the layout \a pLayout, the target + * value specified by the \a target constant and the parent + * \a pParent. + */ + ConsoleAppender(Layout *pLayout, + Target target, + QObject *pParent = 0); + + virtual ~ConsoleAppender(); + private: + ConsoleAppender(const ConsoleAppender &rOther); // Not implemented + ConsoleAppender &operator=(const ConsoleAppender &rOther); // Not implemented + + public: + // JAVA: bool follow() const; + QString target() const; + // JAVA: void setFollow(bool follow); + void setTarget(const QString &rTarget); + + /*! + * Sets the target to the value specified by the \a target constant. + */ + void setTarget(Target target); + + virtual void activateOptions(); + virtual void close(); + + protected: + void closeStream(); + + #ifndef QT_NO_DEBUG_STREAM + /*! + * Writes all object member variables to the given debug stream + * \a rDebug and returns the stream. + * + * + * %ConsoleAppender(name:"CA" filter:0x0 isactive:true isclosed:false + * layout:"PL" target:"STDERR" referenceCount:1 + * threshold:"WARN_SET") + * + * \sa QDebug, operator<<(QDebug debug, const LogObject &rLogObject) + */ + virtual QDebug debug(QDebug &rDebug) const; + #endif // QT_NO_DEBUG_STREAM + + private: + volatile Target mTarget; + QTextStream *mpTextStream; + }; + + + /************************************************************************** + * Operators, Helper + **************************************************************************/ + + + /************************************************************************** + * Inline + **************************************************************************/ + + inline void ConsoleAppender::setTarget(Target target) + { // QMutexLocker locker(&mObjectGuard); // Read/Write of int is safe + mTarget = target; } + + +} // namespace Log4Qt + + +// Q_DECLARE_TYPEINFO(Log4Qt::ConsoleAppender, Q_COMPLEX_TYPE); // Use default + + +#endif // LOG4QT_CONSOLEAPPENDER_H diff --git a/src/log4qt/src/log4qt/dailyrollingfileappender.cpp b/src/log4qt/src/log4qt/dailyrollingfileappender.cpp new file mode 100644 index 0000000..0590f16 --- /dev/null +++ b/src/log4qt/src/log4qt/dailyrollingfileappender.cpp @@ -0,0 +1,352 @@ +/****************************************************************************** + * + * package: Log4Qt + * file: dailyrollingfileappender.cpp + * created: September 2007 + * author: Martin Heinrich + * + * + * Copyright 2007 Martin Heinrich + * + * 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. + * + ******************************************************************************/ + + + +/****************************************************************************** + * Dependencies + ******************************************************************************/ + + +#include "log4qt/dailyrollingfileappender.h" + +#include +#include +#include +#include +#include "log4qt/helpers/datetime.h" +#include "log4qt/layout.h" +#include "log4qt/loggingevent.h" + + + +namespace Log4Qt +{ + + + /************************************************************************** + * Declarations + **************************************************************************/ + + + + /************************************************************************** + * C helper functions + **************************************************************************/ + + + + /************************************************************************** + * Class implementation: DailyRollingFileAppender + **************************************************************************/ + + + DailyRollingFileAppender::DailyRollingFileAppender(QObject *pParent) : + FileAppender(pParent), + mDatePattern() + { + setDatePattern(DAILY_ROLLOVER); + } + + + DailyRollingFileAppender::DailyRollingFileAppender(Layout *pLayout, + const QString &rFileName, + const QString &rDatePattern, + QObject *pParent) : + FileAppender(pLayout, rFileName, pParent), + mDatePattern() + { + setDatePattern(rDatePattern); + } + + + DailyRollingFileAppender::~DailyRollingFileAppender() + { + close(); + } + + + void DailyRollingFileAppender::setDatePattern(DatePattern datePattern) + { + switch (datePattern) + { + case MINUTELY_ROLLOVER: + setDatePattern(QLatin1String("'.'yyyy-MM-dd-hh-mm")); + break; + case HOURLY_ROLLOVER: + setDatePattern(QLatin1String("'.'yyyy-MM-dd-hh")); + break; + case HALFDAILY_ROLLOVER: + setDatePattern(QLatin1String("'.'yyyy-MM-dd-a")); + break; + case DAILY_ROLLOVER: + setDatePattern(QLatin1String("'.'yyyy-MM-dd")); + break; + case WEEKLY_ROLLOVER: + setDatePattern(QLatin1String("'.'yyyy-ww")); + break; + case MONTHLY_ROLLOVER: + setDatePattern(QLatin1String("'.'yyyy-MM")); + break; + default: + Q_ASSERT_X(false, "DailyRollingFileAppender::setDatePattern()", "Invalid datePattern constant"); + setDatePattern(DAILY_ROLLOVER); + }; + } + + + void DailyRollingFileAppender::activateOptions() + { + QMutexLocker locker(&mObjectGuard); + + computeFrequency(); + if (!mActiveDatePattern.isEmpty()) + { + computeRollOverTime(); + FileAppender::activateOptions(); + } + } + + + void DailyRollingFileAppender::append(const LoggingEvent &rEvent) + { + // Q_ASSERT_X(, "DailyRollingFileAppender::append()", "Lock must be held by caller") + + if (QDateTime::currentDateTime() > mRollOverTime) + rollOver(); + FileAppender::append(rEvent); + } + + + bool DailyRollingFileAppender::checkEntryConditions() const + { + // Q_ASSERT_X(, "DailyRollingFileAppender::checkEntryConditions()", "Lock must be held by caller") + + if (mActiveDatePattern.isEmpty()) + { + LogError e = LOG4QT_QCLASS_ERROR(QT_TR_NOOP("Use of appender '%1' without having a valid date pattern set"), + APPENDER_USE_INVALID_PATTERN_ERROR); + e << name(); + logger()->error(e); + return false; + } + + return FileAppender::checkEntryConditions(); + } + + +#ifndef QT_NO_DEBUG_STREAM + QDebug DailyRollingFileAppender::debug(QDebug &rDebug) const + { + QString layout_name; + if (layout()) + layout_name = layout()->name(); + QString codec_name; + if (encoding()) + codec_name = QLatin1String(encoding()->name()); + + rDebug.nospace() << "DailyRollingFileAppender(" + << "name:" << name() << " " + << "activedatepattern:" << mActiveDatePattern << " " + << "appendfile:" << appendFile() << " " + << "bufferedio:" << bufferedIo() << " " + << "datepattern:" << datePattern() << " " + << "encoding:" << codec_name << " " + << "frequency:" << frequencyToString() << " " + << "file:" << file() << " " + << "filter:" << firstFilter() << " " + << "immediateflush:" << immediateFlush() << " " + << "isactive:" << isActive() << " " + << "isclosed:" << isClosed() << " " + << "layout:" << layout_name << " " + << "referencecount:" << referenceCount() << " " + << "rollovertime:" << mRollOverTime + << "threshold:" << threshold().toString() + << "writer:" << writer() + << ")"; + return rDebug.space(); + } +#endif // QT_NO_DEBUG_STREAM + + + void DailyRollingFileAppender::computeFrequency() + { + // Q_ASSERT_X(, "DailyRollingFileAppender::computeFrequency()", "Lock must be held by caller") + + const DateTime start_time(QDate(1999, 1, 1), QTime(0, 0)); + const QString start_string = start_time.toString(mDatePattern); + mActiveDatePattern.clear(); + + if (start_string != static_cast(start_time.addSecs(60)).toString(mDatePattern)) + mFrequency = MINUTELY_ROLLOVER; + else if (start_string != static_cast(start_time.addSecs(60 * 60)).toString(mDatePattern)) + mFrequency = HOURLY_ROLLOVER; + else if (start_string != static_cast(start_time.addSecs(60 * 60 * 12)).toString(mDatePattern)) + mFrequency = HALFDAILY_ROLLOVER; + else if (start_string != static_cast(start_time.addDays(1)).toString(mDatePattern)) + mFrequency = DAILY_ROLLOVER; + else if (start_string != static_cast(start_time.addDays(7)).toString(mDatePattern)) + mFrequency = WEEKLY_ROLLOVER; + else if (start_string != static_cast(start_time.addMonths(1)).toString(mDatePattern)) + mFrequency = MONTHLY_ROLLOVER; + else + { + LogError e = LOG4QT_QCLASS_ERROR(QT_TR_NOOP("The pattern '%1' does not specify a frequency for appender '%2'"), + APPENDER_INVALID_PATTERN_ERROR); + e << mDatePattern << name(); + logger()->error(e); + return; + } + + mActiveDatePattern = mDatePattern; + logger()->trace("Frequency set to %2 using date pattern %1", + mActiveDatePattern, + frequencyToString()); + } + + + void DailyRollingFileAppender::computeRollOverTime() + { + // Q_ASSERT_X(, "DailyRollingFileAppender::computeRollOverTime()", "Lock must be held by caller") + Q_ASSERT_X(!mActiveDatePattern.isEmpty(), "DailyRollingFileAppender::computeRollOverTime()", "No active date pattern"); + + QDateTime now = QDateTime::currentDateTime(); + QDate now_date = now.date(); + QTime now_time = now.time(); + QDateTime start; + + switch (mFrequency) + { + case MINUTELY_ROLLOVER: + { + start = QDateTime(now_date, + QTime(now_time.hour(), + now_time.minute(), + 0, 0)); + mRollOverTime = start.addSecs(60); + } + break; + case HOURLY_ROLLOVER: + { + start = QDateTime(now_date, + QTime(now_time.hour(), + 0, 0, 0)); + mRollOverTime = start.addSecs(60*60); + } + break; + case HALFDAILY_ROLLOVER: + { + int hour = now_time.hour(); + if (hour >= 12) + hour = 12; + else + hour = 0; + start = QDateTime(now_date, + QTime(hour, 0, 0, 0)); + mRollOverTime = start.addSecs(60*60*12); + } + break; + case DAILY_ROLLOVER: + { + start = QDateTime(now_date, + QTime(0, 0, 0, 0)); + mRollOverTime = start.addDays(1); + } + break; + case WEEKLY_ROLLOVER: + { + // QT numbers the week days 1..7. The week starts on Monday. + // Change it to being numbered 0..6, starting with Sunday. + int day = now_date.dayOfWeek(); + if (day == Qt::Sunday) + day = 0; + start = QDateTime(now_date, + QTime(0, 0, 0, 0)).addDays(-1 * day); + mRollOverTime = start.addDays(7); + } + break; + case MONTHLY_ROLLOVER: + { + start = QDateTime(QDate(now_date.year(), + now_date.month(), + 1), + QTime(0, 0, 0, 0)); + mRollOverTime = start.addMonths(1); + } + break; + default: + Q_ASSERT_X(false, "DailyRollingFileAppender::computeInterval()", "Invalid datePattern constant"); + mRollOverTime = QDateTime::fromTime_t(0); + } + + mRollOverSuffix = static_cast(start).toString(mActiveDatePattern); + Q_ASSERT_X(static_cast(now).toString(mActiveDatePattern) == mRollOverSuffix, + "DailyRollingFileAppender::computeRollOverTime()", "File name changes within interval"); + Q_ASSERT_X(mRollOverSuffix != static_cast(mRollOverTime).toString(mActiveDatePattern), + "DailyRollingFileAppender::computeRollOverTime()", "File name does not change with rollover"); + + logger()->trace("Computing roll over time from %1: The interval start time is %2. The roll over time is %3", + now, + start, + mRollOverTime); + } + + + QString DailyRollingFileAppender::frequencyToString() const + { + QMetaEnum meta_enum = metaObject()->enumerator(metaObject()->indexOfEnumerator("DatePattern")); + return QLatin1String(meta_enum.valueToKey(mFrequency)); + } + + + void DailyRollingFileAppender::rollOver() + { + // Q_ASSERT_X(, "DailyRollingFileAppender::rollOver()", "Lock must be held by caller") + Q_ASSERT_X(!mActiveDatePattern.isEmpty(), "DailyRollingFileAppender::rollOver()", "No active date pattern"); + + QString roll_over_suffix = mRollOverSuffix; + computeRollOverTime(); + if (roll_over_suffix == mRollOverSuffix) + return; + + closeFile(); + + QString target_file_name = file() + roll_over_suffix; + QFile f(target_file_name); + if (f.exists() && !removeFile(f)) + return; + f.setFileName(file()); + if (!renameFile(f, target_file_name)) + return; + openFile(); + } + + + + /************************************************************************** + * Implementation: Operators, Helper + **************************************************************************/ + + +} // namespace Log4Qt diff --git a/src/log4qt/src/log4qt/dailyrollingfileappender.h b/src/log4qt/src/log4qt/dailyrollingfileappender.h new file mode 100644 index 0000000..e3fe638 --- /dev/null +++ b/src/log4qt/src/log4qt/dailyrollingfileappender.h @@ -0,0 +1,196 @@ +/****************************************************************************** + * + * package: Log4Qt + * file: dailyrollingfileappender.h + * created: September 2007 + * author: Martin Heinrich + * + * + * Copyright 2007 Martin Heinrich + * + * 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. + * + ******************************************************************************/ + +#ifndef LOG4QT_DAILYROLLINGFILEAPPENDER_H +#define LOG4QT_DAILYROLLINGFILEAPPENDER_H + + +/****************************************************************************** + * Dependencies + ******************************************************************************/ + +#include "log4qt/fileappender.h" + +#include + + +/****************************************************************************** + * Declarations + ******************************************************************************/ + +namespace Log4Qt +{ + + /*! + * \brief The class DailyRollingFileAppender extends FileAppender so that the + * underlying file is rolled over at a specified frequency. + * + * \note All the functions declared in this class are thread-safe. + * + * \note The ownership and lifetime of objects of this class are managed. See + * \ref Ownership "Object ownership" for more details. + */ + class DailyRollingFileAppender : public FileAppender + { + Q_OBJECT + + /*! + * The property holds the date pattern used by the appender. + * + * The default is DAILY_ROLLOVER for rollover at midnight each day. + * + * \sa datePattern(), setDatePattern() + */ + Q_PROPERTY(QString datePattern READ datePattern WRITE setDatePattern) + + public: + /*! + * The enum DatePattern defines constants for date patterns. + * + * \sa setDatePattern(DatePattern) + */ + enum DatePattern + { + /*! The minutely date pattern string is "'.'yyyy-MM-dd-hh-mm". */ + MINUTELY_ROLLOVER = 0, + /*! The hourly date pattern string is "'.'yyyy-MM-dd-hh". */ + HOURLY_ROLLOVER, + /*! The half-daily date pattern string is "'.'yyyy-MM-dd-a". */ + HALFDAILY_ROLLOVER, + /*! The daily date pattern string is "'.'yyyy-MM-dd". */ + DAILY_ROLLOVER, + /*! The weekly date pattern string is "'.'yyyy-ww". */ + WEEKLY_ROLLOVER, + /*! The monthly date pattern string is "'.'yyyy-MM". */ + MONTHLY_ROLLOVER + }; + Q_ENUMS(DatePattern) + + DailyRollingFileAppender(QObject *pParent = 0); + DailyRollingFileAppender(Layout *pLayout, + const QString &rFileName, + const QString &rDatePattern, + QObject *pParent = 0); + virtual ~DailyRollingFileAppender(); + private: + DailyRollingFileAppender(const DailyRollingFileAppender &rOther); // Not implemented + DailyRollingFileAppender &operator=(const DailyRollingFileAppender &rOther); // Not implemented + + public: + QString datePattern() const; + + /*! + * Sets the datePattern to the value specified by the \a datePattern + * constant. + */ + void setDatePattern(DatePattern datePattern); + + void setDatePattern(const QString &rDatePattern); + + virtual void activateOptions(); + + protected: + virtual void append(const LoggingEvent &rEvent); + + /*! + * Tests if all entry conditions for using append() in this class are + * met. + * + * If a conditions is not met, an error is logged and the function + * returns false. Otherwise the result of + * FileAppender::checkEntryConditions() is returned. + * + * The checked conditions are: + * - A valid pattern has been set (APPENDER_USE_INVALID_PATTERN_ERROR) + * + * The function is called as part of the checkEntryConditions() chain + * started by AppenderSkeleton::doAppend(). + * + * \sa AppenderSkeleton::doAppend(), + * AppenderSkeleton::checkEntryConditions() + */ + virtual bool checkEntryConditions() const; + + protected: +#ifndef QT_NO_DEBUG_STREAM + /*! + * Writes all object member variables to the given debug stream + * \a rDebug and returns the stream. + * + * + * %DailyRollingFileAppender(name:"DRFA" activedatepattern:"'.'yyyy-MM-dd-hh-mm" + * appendfile:false bufferedio:true + * datepattern:"'.'yyyy-MM-dd-hh-mm" + * encoding:"" frequency:"MINUTELY_ROLLOVER" + * file:"/log.txt" filter:0x0 immediateflush:true + * isactive:true isclosed:false layout:"TTCC" + * referencecount:1 + * rollovertime:QDateTime("Mon Oct 22 05:23:00 2007") + * threshold: "NULL" writer: 0x0 ) + * + * \sa QDebug, operator<<(QDebug debug, const LogObject &rLogObject) + */ + virtual QDebug debug(QDebug &rDebug) const; +#endif // QT_NO_DEBUG_STREAM + + private: + void computeFrequency(); + void computeRollOverTime(); + QString frequencyToString() const; + void rollOver(); + + private: + QString mDatePattern; + DatePattern mFrequency; + QString mActiveDatePattern; + QDateTime mRollOverTime; + QString mRollOverSuffix; + }; + + + /************************************************************************** + * Operators, Helper + **************************************************************************/ + + + /************************************************************************** + * Inline + **************************************************************************/ + + inline QString DailyRollingFileAppender::datePattern() const + { QMutexLocker locker(&mObjectGuard); + return mDatePattern; } + + inline void DailyRollingFileAppender::setDatePattern(const QString &rDatePattern) + { QMutexLocker locker(&mObjectGuard); + mDatePattern = rDatePattern; } + + +} // namespace Log4Qt + + +// Q_DECLARE_TYPEINFO(Log4Qt::DailyRollingFileAppender, Q_COMPLEX_TYPE); // Use default + + +#endif // LOG4QT_DAILYROLLINGFILEAPPENDER_H diff --git a/src/log4qt/src/log4qt/fileappender.cpp b/src/log4qt/src/log4qt/fileappender.cpp new file mode 100644 index 0000000..265634f --- /dev/null +++ b/src/log4qt/src/log4qt/fileappender.cpp @@ -0,0 +1,307 @@ +/****************************************************************************** + * + * package: Log4Qt + * file: fileappender.cpp + * created: September 2007 + * author: Martin Heinrich + * + * + * Copyright 2007 Martin Heinrich + * + * 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. + * + ******************************************************************************/ + + + +/****************************************************************************** + * Dependencies + ******************************************************************************/ + + +#include "log4qt/fileappender.h" + +#include +#include +#include +#include +#include +#include +#include "log4qt/layout.h" +#include "log4qt/loggingevent.h" + + + +namespace Log4Qt +{ + + + /************************************************************************** + * Declarations + **************************************************************************/ + + + + /************************************************************************** + * C helper functions + **************************************************************************/ + + + + /************************************************************************** + * Class implementation: FileAppender + **************************************************************************/ + + + FileAppender::FileAppender(QObject *pParent) : + WriterAppender(pParent), + mAppendFile(false), + mBufferedIo(true), + mFileName(), + mpFile(0), + mpTextStream(0) + { + } + + + FileAppender::FileAppender(Layout *pLayout, + const QString &rFileName, + QObject *pParent) : + WriterAppender(pLayout, pParent), + mAppendFile(false), + mBufferedIo(true), + mFileName(rFileName), + mpFile(0), + mpTextStream(0) + { + } + + + FileAppender::FileAppender(Layout *pLayout, + const QString &rFileName, + bool append, + QObject *pParent) : + WriterAppender(pLayout, pParent), + mAppendFile(append), + mBufferedIo(true), + mFileName(rFileName), + mpFile(0), + mpTextStream(0) + { + } + + + FileAppender::FileAppender(Layout *pLayout, + const QString &rFileName, + bool append, + bool buffered, + QObject *pParent) : + WriterAppender(pLayout, pParent), + mAppendFile(append), + mBufferedIo(buffered), + mFileName(rFileName), + mpFile(0), + mpTextStream(0) + { + } + + + FileAppender::~FileAppender() + { + close(); + } + + + void FileAppender::activateOptions() + { + QMutexLocker locker(&mObjectGuard); + + if (mFileName.isEmpty()) + { + LogError e = LOG4QT_QCLASS_ERROR(QT_TR_NOOP("Activation of Appender '%1' that requires file and has no file set"), + APPENDER_ACTIVATE_MISSING_FILE_ERROR); + e << name(); + logger()->error(e); + return; + } + closeFile(); + openFile(); + WriterAppender::activateOptions(); + } + + + void FileAppender::close() + { + QMutexLocker locker(&mObjectGuard); + + if (isClosed()) + return; + + WriterAppender::close(); + closeFile(); + } + + + bool FileAppender::checkEntryConditions() const + { + // Q_ASSERT_X(, "FileAppender::checkEntryConditions()", "Lock must be held by caller") + + if (!mpFile || !mpTextStream) + { + LogError e = LOG4QT_QCLASS_ERROR(QT_TR_NOOP("Use of appender '%1' without open file"), + APPENDER_NO_OPEN_FILE_ERROR); + e << name(); + logger()->error(e); + return false; + } + + return WriterAppender::checkEntryConditions(); + } + + + void FileAppender::closeFile() + { + // Q_ASSERT_X(, "FileAppender::closeFile()", "Lock must be held by caller") + + if (mpFile) + logger()->debug("Closing file '%1' for appender '%2'", mpFile->fileName(), name()); + + setWriter(0); + delete mpTextStream; + mpTextStream = 0; + delete mpFile; + mpFile = 0; + } + + +#ifndef QT_NO_DEBUG_STREAM + QDebug FileAppender::debug(QDebug &rDebug) const + { + QString layout_name; + if (layout()) + layout_name = layout()->name(); + QString codec_name; + if (encoding()) + codec_name = QLatin1String(encoding()->name()); + + rDebug.nospace() << "FileAppender(" + << "name:" << name() << " " + << "appendfile:" << appendFile() << " " + << "bufferedio:" << bufferedIo() << " " + << "encoding:" << codec_name << " " + << "file:" << file() << " " + << "filter:" << firstFilter() << " " + << "immediateflush:" << immediateFlush() << " " + << "isactive:" << isActive() << " " + << "isclosed:" << isClosed() << " " + << "layout:" << layout_name << " " + << "referencecount:" << referenceCount() << " " + << "threshold:" << threshold().toString() << " " + << "writer:" << writer() + << ")"; + return rDebug.space(); + } +#endif // QT_NO_DEBUG_STREAM + + + bool FileAppender::handleIoErrors() const + { + // Q_ASSERT_X(, "FileAppender::handleIoErrors()", "Lock must be held by caller") + + if (mpFile->error() == QFile::NoError) + return false; + + LogError e = LOG4QT_QCLASS_ERROR(QT_TR_NOOP("Unable to write to file '%1' for appender '%2'"), + APPENDER_WRITING_FILE_ERROR); + e << mFileName << name(); + e.addCausingError(LogError(mpFile->errorString(), mpFile->error())); + logger()->error(e); + return true; + } + + + void FileAppender::openFile() + { + Q_ASSERT_X(mpFile == 0 && mpTextStream == 0, "FileAppender::openFile()", "Opening file without closing previous file"); + + QFileInfo file_info(mFileName); + QDir parent_dir = file_info.dir(); + if (!parent_dir.exists()) + { + logger()->trace("Creating missing parent directory for file %1", mFileName); + QString name = parent_dir.dirName(); + parent_dir.cdUp(); + parent_dir.mkdir(name); + } + + + mpFile = new QFile(mFileName); + QFile::OpenMode mode = QIODevice::WriteOnly | QIODevice::Text; + if (mAppendFile) + mode |= QIODevice::Append; + else + mode |= QIODevice::Truncate; + if (!mBufferedIo) + mode |= QIODevice::Unbuffered; + if (!mpFile->open(mode)) + { + LogError e = LOG4QT_QCLASS_ERROR(QT_TR_NOOP("Unable to open file '%1' for appender '%2'"), + APPENDER_OPENING_FILE_ERROR); + e << mFileName << name(); + e.addCausingError(LogError(mpFile->errorString(), mpFile->error())); + logger()->error(e); + return; + } + mpTextStream = new QTextStream(mpFile); + setWriter(mpTextStream); + logger()->debug("Opened file '%1' for appender '%2'", mpFile->fileName(), name()); + } + + + bool FileAppender::removeFile(QFile &rFile) const + { + if (rFile.remove()) + return true; + + LogError e = LOG4QT_QCLASS_ERROR(QT_TR_NOOP("Unable to remove file '%1' for appender '%2'"), + APPENDER_REMOVE_FILE_ERROR); + e << rFile.fileName() << name(); + e.addCausingError(LogError(rFile.errorString(), rFile.error())); + logger()->error(e); + return false; + } + + + bool FileAppender::renameFile(QFile &rFile, + const QString &rFileName) const + { + logger()->debug("Renaming file '%1' to '%2'", rFile.fileName(), rFileName); + if (rFile.rename(rFileName)) + return true; + + LogError e = LOG4QT_QCLASS_ERROR(QT_TR_NOOP("Unable to rename file '%1' to '%2' for appender '%3'"), + APPENDER_RENAMING_FILE_ERROR); + e << rFile.fileName() << rFileName << name(); + e.addCausingError(LogError(rFile.errorString(), rFile.error())); + logger()->error(e); + return false; + } + + + + /************************************************************************** + * Implementation: Operators, Helper + **************************************************************************/ + + +} // namespace Log4Qt diff --git a/src/log4qt/src/log4qt/fileappender.h b/src/log4qt/src/log4qt/fileappender.h new file mode 100644 index 0000000..2479d4e --- /dev/null +++ b/src/log4qt/src/log4qt/fileappender.h @@ -0,0 +1,233 @@ +/****************************************************************************** + * + * package: Log4Qt + * file: fileappender.h + * created: September 2007 + * author: Martin Heinrich + * + * + * Copyright 2007 Martin Heinrich + * + * 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. + * + ******************************************************************************/ + +#ifndef LOG4QT_FILEAPPENDER_H +#define LOG4QT_FILEAPPENDER_H + + +/****************************************************************************** + * Dependencies + ******************************************************************************/ + +#include "log4qt/writerappender.h" + + +/****************************************************************************** + * Declarations + ******************************************************************************/ + +class QFile; +class QTextStream; + +namespace Log4Qt +{ + + /*! + * \brief The class FileAppender appends log events to a file. + * + * \note All the functions declared in this class are thread-safe. + * + * \note The ownership and lifetime of objects of this class are managed. See + * \ref Ownership "Object ownership" for more details. + */ + class FileAppender : public WriterAppender + { + Q_OBJECT + + /*! + * The property holds, if the output is appended to the file. + * + * The default is false for not appending. + * + * \sa appendFile(), setAppendFile() + */ + Q_PROPERTY(bool appendFile READ appendFile WRITE setAppendFile) + + /*! + * The property holds, if the output is buffered. + * + * The default is true for buffering. + * + * \sa bufferedIo(), setBufferedIo() + */ + Q_PROPERTY(bool bufferedIo READ bufferedIo WRITE setBufferedIo) + + /*! + * The property holds the name of the file. + * + * \sa file(), setFile() + */ + Q_PROPERTY(QString file READ file WRITE setFile) + + public: + FileAppender(QObject *pParent = 0); + FileAppender(Layout *pLayout, + const QString &rFileName, + QObject *pParent = 0); + FileAppender(Layout *pLayout, + const QString &rFileName, + bool append, + QObject *pParent = 0); + FileAppender(Layout *pLayout, + const QString &rFileName, + bool append, + bool buffered, + QObject *pParent = 0); + virtual ~FileAppender(); + private: + FileAppender(const FileAppender &rOther); // Not implemented + FileAppender &operator=(const FileAppender &rOther); // Not implemented + + public: + bool appendFile() const; + QString file() const; + bool bufferedIo() const; + // JAVA: int bufferSize() const; + void setAppendFile(bool append); + void setBufferedIo(bool buffered); + // JAVA: void setBufferSize(int bufferSize); + void setFile(const QString &rFileName); + + virtual void activateOptions(); + virtual void close(); + + protected: + /*! + * Tests if all entry conditions for using append() in this class are met. + * + * If a conditions is not met, an error is logged and the function returns + * false. Otherwise the result of WriterAppender::checkEntryConditions() + * is returned. + * + * The checked conditions are: + * - That a file is set and open (APPENDER_NO_OPEN_FILE_ERROR) + * + * The function is called as part of the checkEntryConditions() chain + * started by AppenderSkeleton::doAppend(). + * + * \sa AppenderSkeleton::doAppend(), AppenderSkeleton::checkEntryConditions() + */ + virtual bool checkEntryConditions() const; + + void closeFile(); + +#ifndef QT_NO_DEBUG_STREAM + /*! + * Writes all object member variables to the given debug stream \a rDebug + * and returns the stream. + * + * + * %FileAppender(name:"FA" appendfile:false bufferedio:true encoding:"" + * file:"/log.txt" filter: 0x0 immediateflush:true isactive:false + * isclosed:false layout:"TTCC" referencecount:2 + * threshold:"NULL" writer:0x0) + * + * \sa QDebug, operator<<(QDebug debug, const LogObject &rLogObject) + */ + virtual QDebug debug(QDebug &rDebug) const; +#endif // QT_NO_DEBUG_STREAM + + /*! + * Checks for file I/O errrors. If an error is found it is logged and the + * function returns true. Otherwise false is returned. + */ + virtual bool handleIoErrors() const; + + /*! + * Opens the file for the appender based on the specified file name and + * mode. A text stream is created and passed on to the super class + * WriterAppender. + * + * If the parent directory of the specified file does not exists, + * it is created. + */ + void openFile(); + + /*! + * Removes the file \a rFile. If the operation is successful, true is + * returned. Otherwise an APPENDER_REMOVE_FILE_ERROR error is logged + * and false is returned. + */ + bool removeFile(QFile &rFile) const; + + /*! + * Renames the file \a rFile to \a rFileName. If the operation is + * successful, true is returned. Otherwise an + * APPENDER_RENAMING_FILE_ERROR error is logged and false is returned. + */ + bool renameFile(QFile &rFile, + const QString &rFileName) const; + + // JAVA: void setQWForFiles(Writer writer); + + private: + volatile bool mAppendFile; + volatile bool mBufferedIo; + QString mFileName; + QFile *mpFile; + QTextStream *mpTextStream; + }; + + + /************************************************************************** + * Operators, Helper + **************************************************************************/ + + + /************************************************************************** + * Inline + **************************************************************************/ + + inline bool FileAppender::appendFile() const + { // QMutexLocker locker(&mObjectGuard); // Read/Write of int is safe + return mAppendFile; } + + inline QString FileAppender::file() const + { QMutexLocker locker(&mObjectGuard); + return mFileName; } + + inline bool FileAppender::bufferedIo() const + { // QMutexLocker locker(&mObjectGuard); // Read/Write of int is safe + return mBufferedIo; } + + inline void FileAppender::setAppendFile(bool append) + { // QMutexLocker locker(&mObjectGuard); // Read/Write of int is safe + mAppendFile = append; } + + inline void FileAppender::setBufferedIo(bool buffered) + { // QMutexLocker locker(&mObjectGuard); // Read/Write of int is safe + mBufferedIo = buffered; } + + inline void FileAppender::setFile(const QString &rFileName) + { QMutexLocker locker(&mObjectGuard); + mFileName = rFileName; } + + +} // namespace Log4Qt + + +// Q_DECLARE_TYPEINFO(Log4Qt::FileAppender, Q_COMPLEX_TYPE); // Use default + + +#endif // LOG4QT_FILEAPPENDER_H diff --git a/src/log4qt/src/log4qt/helpers/classlogger.cpp b/src/log4qt/src/log4qt/helpers/classlogger.cpp new file mode 100644 index 0000000..50b6c7f --- /dev/null +++ b/src/log4qt/src/log4qt/helpers/classlogger.cpp @@ -0,0 +1,100 @@ +/****************************************************************************** + * + * package: Log4Qt + * file: classlogger.cpp + * created: September 2007 + * author: Martin Heinrich + * + * + * changes: Sep 2008, Martin Heinrich: + * - Replaced usage of q_atomic_test_and_set_ptr with + * QAtomicPointer + * + * + * Copyright 2007 - 2008 Martin Heinrich + * + * 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. + * + ******************************************************************************/ + + + +/****************************************************************************** + * Dependencies + ******************************************************************************/ + + +#include "log4qt/helpers/classlogger.h" + +#include +#include "log4qt/logmanager.h" + + +namespace Log4Qt +{ + + + /************************************************************************** + * Declarations + **************************************************************************/ + + + + /************************************************************************** + * C helper functions + **************************************************************************/ + + + + /************************************************************************** + * Class implementation: ClassLogger + **************************************************************************/ + + + ClassLogger::ClassLogger() : + mpLogger(0) + { + } + + + Logger *ClassLogger::logger(const QObject *pObject) + { + Q_ASSERT_X(pObject, "ClassLogger::logger()", "pObject must not be null"); +#if QT_VERSION < QT_VERSION_CHECK(4, 4, 0) + if (!mpLogger) + q_atomic_test_and_set_ptr(&mpLogger, + 0, + LogManager::logger(QLatin1String(pObject->metaObject()->className()))); + return const_cast(mpLogger); +#elif QT_VERSION < QT_VERSION_CHECK(5, 0, 0) + if (!static_cast(mpLogger)) + mpLogger.testAndSetOrdered(0, + LogManager::logger(QLatin1String(pObject->metaObject()->className()))); + return const_cast(static_cast(mpLogger)); +#else + if (!static_cast(mpLogger.loadAcquire())) + mpLogger.testAndSetOrdered(0, + LogManager::logger(QLatin1String(pObject->metaObject()->className()))); + return const_cast(static_cast(mpLogger.loadAcquire())); +#endif + } + + + + /************************************************************************** + * Implementation: Operators, Helper + **************************************************************************/ + + + +} // namespace Log4Qt diff --git a/src/log4qt/src/log4qt/helpers/classlogger.h b/src/log4qt/src/log4qt/helpers/classlogger.h new file mode 100644 index 0000000..065a852 --- /dev/null +++ b/src/log4qt/src/log4qt/helpers/classlogger.h @@ -0,0 +1,115 @@ +/****************************************************************************** + * + * package: Log4Qt + * file: classlogger.h + * created: September 2007 + * author: Martin Heinrich + * + * + * changes: Sep 2008, Martin Heinrich: + * - Replaced usage of q_atomic_test_and_set_ptr with + * QAtomicPointer + * + * + * Copyright 2007 - 2008 Martin Heinrich + * + * 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. + * + ******************************************************************************/ + +#ifndef LOG4QT_CLASSLOGGER_H +#define LOG4QT_CLASSLOGGER_H + + +/****************************************************************************** + * Dependencies + ******************************************************************************/ + +#include +#if QT_VERSION >= QT_VERSION_CHECK(4, 4, 0) +# include +# ifndef Q_ATOMIC_POINTER_TEST_AND_SET_IS_ALWAYS_NATIVE +# warning "QAtomicPointer test and set is not native. The class Log4Qt::ClassLogger is not thread-safe." +# endif +#endif + + +/****************************************************************************** + * Declarations + ******************************************************************************/ + +namespace Log4Qt +{ + class Logger; + + /*! + * \brief The class ClassLogger provides logging for a QObject derived + * class. + * + * The class ClassLogger provides a logger for a specified QObject derived + * object. It is used by \ref LOG4QT_DECLARE_QCLASS_LOGGER to implement the + * member functions provided by the macro. + * + * \note All the functions declared in this class are thread-safe. + * + * \sa LOG4QT_DECLARE_QCLASS_LOGGER + */ + class ClassLogger + { + public: + /*! + * Creates a ClassLogger object. + */ + ClassLogger(); + // ~ClassLogger(); // Use compiler default + // ClassLogger(const ClassLogger &rOther); // Use compiler default + // ClassLogger &operator=(const ClassLogger &rOther); // Use compiler default + + /*! + * Returns a pointer to a Logger named after the class of the object + * \a pObject. + * + * On the first invocation the Logger is requested by a call to + * LogManager::logger(const char *pName). The pointer is stored to be + * returned on subsequent invocations. + * + * \sa LogManager::logger(const char *pName) + */ + Logger *logger(const QObject *pObject); + + private: +#if QT_VERSION < QT_VERSION_CHECK(4, 4, 0) + volatile Logger *mpLogger; +#else + mutable QAtomicPointer mpLogger; +#endif + }; + + + /****************************************************************************** + * Operators, Helper + ******************************************************************************/ + + + /************************************************************************** + * Inline + **************************************************************************/ + + +} // namespace Log4Qt + + +// Q_DECLARE_TYPEinfo(Log4Qt::ClassLogger, Q_COMPLEX_TYPE); // Use default + + +#endif // LOG4QT_CLASSLOGGER_H diff --git a/src/log4qt/src/log4qt/helpers/configuratorhelper.cpp b/src/log4qt/src/log4qt/helpers/configuratorhelper.cpp new file mode 100644 index 0000000..3b34f40 --- /dev/null +++ b/src/log4qt/src/log4qt/helpers/configuratorhelper.cpp @@ -0,0 +1,136 @@ +/****************************************************************************** + * + * package: Log4Qt + * file: configuratorhelper.cpp + * created: September 2007 + * author: Martin Heinrich + * + * + * Copyright 2007 Martin Heinrich + * + * 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. + * + ******************************************************************************/ + + + +/****************************************************************************** + * Dependencies + ******************************************************************************/ + + +#include "log4qt/helpers/configuratorhelper.h" + +#include +#include +#include "log4qt/helpers/initialisationhelper.h" + + + +namespace Log4Qt +{ + + + /************************************************************************** + * Declarations + **************************************************************************/ + + + + /************************************************************************** + * C helper functions + **************************************************************************/ + + + + /************************************************************************** + * Class implementation: ConfiguratorHelper + **************************************************************************/ + + + ConfiguratorHelper::ConfiguratorHelper() : + mObjectGuard(), + mConfigurationFile(), + mpConfigureFunc(0), + mpConfigurationFileWatch(0), + mConfigureError() + { + } + + + ConfiguratorHelper::~ConfiguratorHelper() + { + delete mpConfigurationFileWatch; + } + + + LOG4QT_IMPLEMENT_INSTANCE(ConfiguratorHelper) + + + void ConfiguratorHelper::doConfigurationFileChanged(const QString &rFileName) + { + QMutexLocker locker(&mObjectGuard); + + if (!mpConfigureFunc) + return; + mpConfigureFunc(rFileName); + // Shall we hold the lock while emitting the signal? + emit configurationFileChanged(rFileName, mConfigureError.count() > 0); + } + + + + void ConfiguratorHelper::doSetConfigurationFile(const QString &rFileName, + ConfigureFunc pConfigureFunc) + { + QMutexLocker locker(&mObjectGuard); + + mConfigurationFile.clear(); + mpConfigureFunc = 0; + delete mpConfigurationFileWatch; + if (rFileName.isEmpty()) + return; + + mConfigurationFile = rFileName; + mpConfigureFunc = pConfigureFunc; + mpConfigurationFileWatch = new QFileSystemWatcher(); + mpConfigurationFileWatch->addPath(rFileName); + connect(mpConfigurationFileWatch, + SIGNAL(fileChanged(const QString &)), + SLOT(configurationFileChanged(const QString &))); + } + + + + /************************************************************************** + * Implementation: Operators, Helper + **************************************************************************/ + + +#ifndef QT_NO_DEBUG_STREAM + QDebug operator<<(QDebug debug, + const ConfiguratorHelper &rConfiguratorHelper) + { + debug.nospace() << "ConfiguratorHelper(" + << "configurationfile:" << ConfiguratorHelper::configurationFile() + << "configurefunc:" << rConfiguratorHelper.mpConfigureFunc + << "filesystemwatcher:" << rConfiguratorHelper.mpConfigurationFileWatch + << ")"; + return debug.space(); + } +#endif // QT_NO_DEBUG_STREAM + + + +} // namespace Log4Qt + diff --git a/src/log4qt/src/log4qt/helpers/configuratorhelper.h b/src/log4qt/src/log4qt/helpers/configuratorhelper.h new file mode 100644 index 0000000..765f86a --- /dev/null +++ b/src/log4qt/src/log4qt/helpers/configuratorhelper.h @@ -0,0 +1,210 @@ +/****************************************************************************** + * + * package: Log4Qt + * file: configuratorhelper.h + * created: September 2007 + * author: Martin Heinrich + * + * + * Copyright 2007 Martin Heinrich + * + * 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. + * + ******************************************************************************/ + +#ifndef LOG4QT_HELPERS_CONFIGURATORHELPER_H +#define LOG4QT_HELPERS_CONFIGURATORHELPER_H + + +/****************************************************************************** + * Dependencies + ******************************************************************************/ + +#include + +#include +#include +#include "log4qt/loggingevent.h" + + +/****************************************************************************** + * Declarations + ******************************************************************************/ + +class QFileSystemWatcher; + + +namespace Log4Qt +{ + + /*! + * \brief The class ConfiguratorHelper provides a confiuration file watch + * and last error for configurator classes. + * + * A configuration file can be set using setConfigurationFile(). The file + * is watched for changes. If a change occurs the configuration is reloaded + * and the ConfigurationFileChanged() signal is emitted. Error information + * for the last call to a configure function or the last configuration file + * change can be accessed using configureError(). + * + * \note All the functions declared in this class are thread-safe. + */ + class ConfiguratorHelper : public QObject + { + Q_OBJECT + + public: + /*! + * Prototype for a configure callback function. The function is called + * when then configuration file is changed and takes the + * configuration file as a parameter. + * + * \sa setConfigurationFile(), + * PropertyConfigurator::configure(const QString &) + */ + typedef bool (*ConfigureFunc)(const QString &rFileName); + + private: + ConfiguratorHelper(); + ConfiguratorHelper(const ConfiguratorHelper &rOther); // Not implemented + virtual ~ConfiguratorHelper(); + ConfiguratorHelper &operator=(const ConfiguratorHelper &rOther); // Not implemented + + public: + + /*! + * Returns the error information for the last configuration operation + * that took place. The configuration operation could be the result of + * a call to one of the configure methods or through a change + * to the configuration file. + * + * \sa setConfigureError(), PropertyConfigurator::configure(), + * setConfigurationFile() + */ + static QList configureError(); + + /*! + * Returns the current configuration file. + * + * \sa setConfigurationFile() + */ + static QString configurationFile(); + + /*! + * Returns the ConfiguratorHelper instance. + */ + static ConfiguratorHelper *instance(); + + /*! + * Sets the configuration error information for the last configuration + * operation. + * + * \sa configureError() + */ + static void setConfigureError(const QList &rConfigureError); + + /*! + * Sets the configuration file to \a rFileName. The file is watched for + * changes. On a file change the function \a pConfigureFunc will be called + * and the signal configurationFileChange() will be emitted. + * + * Setting the configuration file to an empty string stops the file watch. + * + * \sa configurationFile(), PropertyConfigurator::configureAndWatch(), + * configureError() + */ + static void setConfigurationFile(const QString &rFileName = QString(), + ConfigureFunc pConfigureFunc = 0); + + signals: + /*! + * The signal is emitted after a change to the file \a rFileName + * was processed. If an error occured during the configuration, the + * flag \a error will be true and error information is available + * over configureError(). + */ + void configurationFileChanged(const QString &rFileName, + bool error); + + private slots: + void doConfigurationFileChanged(const QString &rFileName); + + private: + void doSetConfigurationFile(const QString &rFileName, + ConfigureFunc pConfigureFunc); + + private: + mutable QMutex mObjectGuard; + QString mConfigurationFile; + ConfigureFunc mpConfigureFunc; + QFileSystemWatcher *mpConfigurationFileWatch; + QList mConfigureError; + +#ifndef QT_NO_DEBUG_STREAM + // Needs to be friend to access details + friend QDebug operator<<(QDebug debug, + const ConfiguratorHelper &rConfiguratorHelper); +#endif // QT_NO_DEBUG_STREAM + }; + + + /************************************************************************** + * Operators, Helper + **************************************************************************/ + +#ifndef QT_NO_DEBUG_STREAM + /*! + * \relates ConfiguratorHelper + * + * Writes all object member variables to the given debug stream \a rDebug and + * returns the stream. + * + * + * %ConfiguratorHelper(configurationfile: "" configurefunc: false + * filesystemwatcher: QObject(0x0) ) + * + * \sa QDebug, ConfiguratorHelper::logManager() + */ + QDebug operator<<(QDebug debug, + const ConfiguratorHelper &rConfiguratorHelper); +#endif // QT_NO_DEBUG_STREAM + + + + /************************************************************************** + * Inline + **************************************************************************/ + + inline QList ConfiguratorHelper::configureError() + { QMutexLocker locker(&instance()->mObjectGuard); + return instance()->mConfigureError; } + + inline QString ConfiguratorHelper::configurationFile() + { QMutexLocker locker(&instance()->mObjectGuard); + return instance()->mConfigurationFile; } + + inline void ConfiguratorHelper::setConfigureError(const QList &rConfigureError) + { QMutexLocker locker(&instance()->mObjectGuard); + instance()->mConfigureError = rConfigureError; } + + inline void ConfiguratorHelper::setConfigurationFile(const QString &rFileName, + ConfigureFunc pConfigureFunc) + { instance()->doSetConfigurationFile(rFileName, pConfigureFunc); } + +} // namespace Log4Qt + + +// Q_DECLARE_TYPEINFO(Log4Qt::ConfiguratorHelper, Q_COMPLEX_TYPE); // use default + + +#endif // LOG4QT_HELPERS_CONFIGURATORHELPER_H diff --git a/src/log4qt/src/log4qt/helpers/datetime.cpp b/src/log4qt/src/log4qt/helpers/datetime.cpp new file mode 100644 index 0000000..081dc10 --- /dev/null +++ b/src/log4qt/src/log4qt/helpers/datetime.cpp @@ -0,0 +1,326 @@ +/****************************************************************************** + * + * package: Log4Qt + * file: datetime.cpp + * created: September 2007 + * author: Martin Heinrich + * + * + * Copyright 2007 Martin Heinrich + * + * 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. + * + ******************************************************************************/ + + + +/****************************************************************************** + * Dependencies + ******************************************************************************/ + + +#include "log4qt/helpers/datetime.h" + +#include +#include "log4qt/helpers/initialisationhelper.h" + + + +namespace Log4Qt +{ + + + /************************************************************************** + *Declarations + **************************************************************************/ + + + + /************************************************************************** + * C helper functions + **************************************************************************/ + + + + /************************************************************************** + * Class implementation: DateTime + **************************************************************************/ + + + QString DateTime::toString(const QString &rFormat) const + { + QString format(rFormat); + + if (format.isEmpty()) + return QString(); + if (!isValid()) + return QString(); + if (format == QLatin1String("NONE")) + return QString(); + + if (format == QLatin1String("TIME_RELATIVE")) + return QString::number(toMilliSeconds() - InitialisationHelper::startTime()); + + if (format == QLatin1String("ISO8601")) + format = QLatin1String("yyyy-MM-dd hh:mm:ss.zzz"); + if (format == QLatin1String("TIME_ABSOLUTE")) + format = QLatin1String("HH:mm:ss.zzz"); + if (format == QLatin1String("DATE")) + format = QLatin1String("dd MMM YYYY HH:mm:ss.zzzz"); + + return formatDateTime(format); + } + + + QString DateTime::formatDateTime(const QString &rFormat) const + { + if (rFormat.isEmpty()) + return QString(); + if (!isValid()) + return QString(); + + const QLatin1Char null('0'); + const QLatin1Char quote('\''); + const QString tokens = QLatin1String("\'dMyhHmszAPapw"); + const bool am_pm = hasAMPM(rFormat); + + QString result; + QString token; + QChar expected = null; + + QChar c; + int i; + for (i = 0; i < rFormat.length(); i++) + { + c = rFormat.at(i); + + // Handle literal text + if (expected == quote) + { + if (c == quote) + { + Q_ASSERT_X(i > 0, "DateTime::toString()", "Found quote with status quote at i = 0"); + if (i > 0 && rFormat.at(i - 1) == quote) + // Second of two quotes + result += quote; + expected = null; + } + else + // Next literal character + result += c; + } + else if (c == expected) + { + // Extend token + token += c; + } + else + { + // Close last token + result += formatToken(token, am_pm); + token.clear(); + expected = null; + + // Test for valid character + if (tokens.indexOf(c) >= 0) + { + if (c == QLatin1Char('a')) + expected = QLatin1Char('p'); + else if (c == QLatin1Char('A')) + expected = QLatin1Char('P'); + else if (c.toLower() == QLatin1Char('p')) + expected = null; + else + expected = c; + if (c != quote) + token += c; + } else + result += c; + } + } + + result += formatToken(token, am_pm); + return result; + } + + + QString DateTime::formatToken(const QString &rToken, bool am_pm) const + { + if (rToken.isEmpty()) + return QString(); + + const QChar c = rToken.at(0); + QString result; + int used; + + // Qt data format strings + if (rToken.startsWith(QLatin1String("dddd"))) + { + result = QDate::longDayName(date().dayOfWeek()); + used = 4; + } + else if (rToken.startsWith(QLatin1String("ddd"))) + { + result = QDate::shortDayName(date().dayOfWeek()); + used = 3; + } + else if (rToken.startsWith(QLatin1String("dd"))) + { + result = QString::number(date().day()).rightJustified(2, QLatin1Char('0'), true); + used = 2; + } + else if (c == QLatin1Char('d')) + { + result = QString::number(date().day()); + used = 1; + } + else if (rToken.startsWith(QLatin1String("MMMM"))) + { + result = QDate::longMonthName(date().month()); + used = 4; + } + else if (rToken.startsWith(QLatin1String("MMM"))) + { + result = QDate::shortMonthName(date().month()); + used = 3; + } + else if (rToken.startsWith(QLatin1String("MM"))) + { + result = QString::number(date().month()).rightJustified(2, QLatin1Char('0'), true); + used = 2; + } + else if (c == QLatin1Char('M')) + { + result = QString::number(date().month()); + used = 1; + } + else if (rToken.startsWith(QLatin1String("yyyy"))) + { + result = QString::number(date().year()); + used = 4; + } + else if (rToken.startsWith(QLatin1String("yy"))) + { + result = QString::number(date().year() % 100).rightJustified(2, QLatin1Char('0'), true); + used = 2; + } + + // Qt time format strings + else if (rToken.startsWith(QLatin1String("hh")) || rToken.startsWith(QLatin1String("HH"))) + { + int hour = time().hour(); + if (am_pm && c == QLatin1Char('h') && hour > 12) + hour -= 12; + result = QString::number(hour).rightJustified(2, QLatin1Char('0'), true); + used = 2; + } + else if (c == QLatin1Char('h') || c == QLatin1Char('H')) + { + int hour = time().hour(); + if (am_pm && c == QLatin1Char('h') && hour > 12) + hour -= 12; + result = QString::number(hour); + used = 2; + } + else if (rToken.startsWith(QLatin1String("mm"))) + { + result = QString::number(time().minute()).rightJustified(2, QLatin1Char('0'), true); + used = 2; + } + else if (c == (QLatin1Char('m'))) + { + result = QString::number(time().minute()); + used = 1; + } + else if (rToken.startsWith(QLatin1String("ss"))) + { + result = QString::number(time().second()).rightJustified(2, QLatin1Char('0'), true); + used = 2; + } + else if (c == QLatin1Char('s')) + { + result = QString::number(time().second()); + used = 1; + } + else if (rToken.startsWith(QLatin1String("zzz"))) + { + result = QString::number(time().msec()).rightJustified(3, QLatin1Char('0'), true); + used = 3; + } + else if (c == QLatin1Char('z')) + { + result = QString::number(time().msec()); + used = 1; + } + else if (c.toLower() == QLatin1Char('a')) + { + bool is_lower = c == QLatin1Char('a'); + if (time().hour() < 12) + result = QLatin1String("AM"); + else + result = QLatin1String("PM"); + if (is_lower) + result = result.toLower(); + if (rToken.size() > 1 && + ((is_lower && rToken.at(1) == QLatin1Char('p')) || + (!is_lower && rToken.at(1) == QLatin1Char('P'))) + ) + used = 2; + else + used = 1; + } + + // Extension for week number + else if (rToken.startsWith(QLatin1String("ww"))) + { + result = QString::number(date().weekNumber()).rightJustified(2, QLatin1Char('0'), true); + used = 2; + } + else if (c == QLatin1Char('w')) + { + result = QString::number(date().weekNumber()); + used = 1; + } + + if (used) + return result + formatToken(rToken.mid(used), am_pm); + else + return result; + } + + + bool DateTime::hasAMPM(const QString &rToken) + { + bool in_literal = false; + QChar c; + int i; + for (i = 0; i < rToken.length(); i++) + { + c = rToken.at(i); + if (c == QLatin1Char('\'')) + in_literal = !in_literal; + else if (!in_literal && c.toLower() == QLatin1Char('a')) + return true; + } + return false; + } + + + + /************************************************************************** + * Implementation: Operators, Helper + **************************************************************************/ + + + +} // namespace Log4Qt diff --git a/src/log4qt/src/log4qt/helpers/datetime.h b/src/log4qt/src/log4qt/helpers/datetime.h new file mode 100644 index 0000000..0b89735 --- /dev/null +++ b/src/log4qt/src/log4qt/helpers/datetime.h @@ -0,0 +1,212 @@ +/****************************************************************************** + * + * package: Log4Qt + * file: datetime.h + * created: September 2007 + * author: Martin Heinrich + * + * + * changes: Sep 2008, Martin Heinrich: + * - Resolved compilation problem with Microsoft Visual Studio 2005 + * + * + * Copyright 2007 - 2008 Martin Heinrich + * + * 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. + * + ******************************************************************************/ + +#ifndef LOG4QT_HELPERS_DATETIME_H +#define LOG4QT_HELPERS_DATETIME_H + + +/****************************************************************************** + * Dependencies + ******************************************************************************/ + +#include + + +/****************************************************************************** + * Declarations + ******************************************************************************/ + + +namespace Log4Qt +{ + + /*! + * \brief The class DateTime provides extended functionality for QDateTime. + * + * The class DateTime implements additional formatting options for + * toString() and provides conversion functions from and to milliseconds. + */ + class DateTime : public QDateTime + { + public: + /*! + * Constructs a null date time. + * + * \sa QDateTime::QDateTime() + */ + DateTime(); + + // DateTime(const DateTime &rOther); // Use compiler default + + /*! + * Constructs a copy of another QDateTime. + * + * \sa QDateTime::QDateTime(const QDateTime &rOther) + */ + DateTime(const QDateTime &rOther); + + /*! + * Constructs a datetime with the given \a rDate and \a rTime, using + * the time specification defined by \a timeSpec. + * + * \sa QDateTime::QDateTime(const QDate &rDate, const QTime &rTime, + * Qt::TimeSpec timeSpec = Qt::LocalTime) + */ + DateTime(const QDate &rDate, + const QTime &rTime, + Qt::TimeSpec timeSpec = Qt::LocalTime); + + // virtual ~DateTime(); // Use compiler default + + /*! + * Assigns \a rOther to this DateTime and returns a reference to it. + */ + DateTime &operator=(const DateTime &rOther); + + /*! + * Returns the datetime as the number of milliseconds that have passed + * since 1970-01-01T00:00:00,000, Coordinated Universal Time (Qt::UTC). + * + * \sa QDateTime::toTime_t() + */ + qint64 toMilliSeconds() const; + + /*! + * Returns the datetime as a string. The \a rFormat parameter + * determines the format of the result string. + * + * In addition to the expressions of QDateTime::toString(const QString + * &rFormat) the following expression can be used. + * + * + * + * + * + * + * + * + * + * + * + * + *
Expression Output
w the week of the year as number without a leading zero (1 to 53)
ww the week of the year as number with a leading zero (01 to 53)
+ * + * Alternatively the \a rFormat parameter can specify one of the + * following strings. + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + *
String Format
TIME_ABSOLUTE uses the format HH:mm:ss.zzz
DATE uses the format dd MMM YYYY HH:mm:ss.zzzz
ISO8601 uses the format yyyy-MM-dd hh:mm:ss.zzz
NONE uses an empty string as format
TIME_RELATIVE returns the milliseconds since start of the program
+ * + * \sa QDateTime::toString(const QString &rFormat) + */ + QString toString(const QString &rFormat) const; + + /*! + * Returns the current datetime, as reported by the system clock, in + * the local time zone. + * + * \sa QDateTime::currentDateTime() + */ + static DateTime currentDateTime(); + + /*! + * Returns a datetime whose date and time are the number of + * milliseconds that have passed since 1970-01-01T00:00:00, + * Coordinated Universal Time (Qt::UTC). + * + * \sa QDateTime::fromTime_t(uint seconds) + */ + static DateTime fromMilliSeconds(qint64 milliSeconds); + + private: + QString formatDateTime(const QString &rFormat) const; + QString formatToken(const QString &rToken, bool am_pm) const; + static bool hasAMPM(const QString &rFormat); + }; + + + /************************************************************************** + * Operators, Helper + **************************************************************************/ + + + /************************************************************************** + * Inline + **************************************************************************/ + + inline DateTime::DateTime() : QDateTime() + {} + + inline DateTime::DateTime(const QDateTime &rOther) : QDateTime(rOther) + {} + + inline DateTime::DateTime(const QDate &rDate, + const QTime &rTime, + Qt::TimeSpec timeSpec) : + QDateTime(rDate, rTime, timeSpec) + {} + + inline DateTime &DateTime::operator=(const DateTime &rOther) + { QDateTime::operator=(rOther); return *this; } + + inline qint64 DateTime::toMilliSeconds() const + { return (qint64)1000 * toTime_t() + time().msec(); } + + inline DateTime DateTime::currentDateTime() + { return DateTime(QDateTime::currentDateTime()); } + + inline DateTime DateTime::fromMilliSeconds(qint64 milliSeconds) + { return DateTime(QDateTime::fromTime_t(milliSeconds / 1000).addMSecs(milliSeconds % 1000)); } + + +} // namespace Log4Qt + + +Q_DECLARE_TYPEINFO(Log4Qt::DateTime, Q_MOVABLE_TYPE); + + +#endif // LOG4QT_HELPERS_DATETIME_H diff --git a/src/log4qt/src/log4qt/helpers/factory.cpp b/src/log4qt/src/log4qt/helpers/factory.cpp new file mode 100644 index 0000000..bf2f449 --- /dev/null +++ b/src/log4qt/src/log4qt/helpers/factory.cpp @@ -0,0 +1,459 @@ +/****************************************************************************** + * + * package: Log4Qt + * file: factory.cpp + * created: September 2007 + * author: Martin Heinrich + * + * + * Copyright 2007 Martin Heinrich + * + * 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. + * + ******************************************************************************/ + + + +/****************************************************************************** + * Dependencies + ******************************************************************************/ + + +#include "log4qt/helpers/factory.h" + +#include +#include +#include +#include "log4qt/consoleappender.h" +#include "log4qt/dailyrollingfileappender.h" +#include "log4qt/fileappender.h" +#include "log4qt/helpers/logerror.h" +#include "log4qt/helpers/initialisationhelper.h" +#include "log4qt/helpers/optionconverter.h" +#include "log4qt/patternlayout.h" +#include "log4qt/rollingfileappender.h" +#include "log4qt/simplelayout.h" +#include "log4qt/ttcclayout.h" +#include "log4qt/varia/debugappender.h" +#include "log4qt/varia/denyallfilter.h" +#include "log4qt/varia/levelmatchfilter.h" +#include "log4qt/varia/levelrangefilter.h" +#include "log4qt/varia/listappender.h" +#include "log4qt/varia/nullappender.h" +#include "log4qt/varia/stringmatchfilter.h" + + + +namespace Log4Qt +{ + + + /************************************************************************** + * Declarations + **************************************************************************/ + + + + /************************************************************************** + * C helper functions + **************************************************************************/ + + + LOG4QT_DECLARE_STATIC_LOGGER(logger, Log4Qt::Factory) + + + // Appenders + + Appender *console_file_appender() + { return new ConsoleAppender; } + + Appender *create_daily_rolling_file_appender() + { return new DailyRollingFileAppender; } + + Appender *create_debug_appender() + { return new DebugAppender; } + + Appender *create_file_appender() + { return new FileAppender; } + + Appender *create_list_appender() + { return new ListAppender; } + + Appender *create_null_appender() + { return new NullAppender; } + + Appender *create_rolling_file_appender() + { return new RollingFileAppender; } + + + // Filters + + Filter *create_deny_all_filter() + { return new DenyAllFilter; } + + Filter *create_level_match_filter() + { return new LevelMatchFilter; } + + Filter *create_level_range_filter() + { return new LevelRangeFilter; } + + Filter *create_string_match_filter() + { return new StringMatchFilter; } + + + // Layouts + + Layout *create_pattern_layout() + { return new PatternLayout; } + + Layout *create_simple_layout() + { return new SimpleLayout; } + + Layout *create_ttcc_layout() + { return new TTCCLayout; } + + + + /************************************************************************** + * Class implementation: Factory + **************************************************************************/ + + + Factory::Factory() : + mObjectGuard(), + mAppenderRegistry(), + mFilterRegistry(), + mLayoutRegistry() + { + registerDefaultAppenders(); + registerDefaultFilters(); + registerDefaultLayouts(); + } + + + LOG4QT_IMPLEMENT_INSTANCE(Factory) + + + Appender *Factory::doCreateAppender(const QString &rAppenderClassName) + { + QMutexLocker locker(&mObjectGuard); + + if (!mAppenderRegistry.contains(rAppenderClassName)) + { + logger()->warn("Request for the creation of Appender with class '%1', which is not registered", rAppenderClassName); + return 0; + } + return mAppenderRegistry.value(rAppenderClassName)(); + } + + + Filter *Factory::doCreateFilter(const QString &rFilterClassName) + { + QMutexLocker locker(&mObjectGuard); + + if (!mFilterRegistry.contains(rFilterClassName)) + { + logger()->warn("Request for the creation of Filter with class '%1', which is not registered", rFilterClassName); + return 0; + } + return mFilterRegistry.value(rFilterClassName)(); + } + + + Layout *Factory::doCreateLayout(const QString &rLayoutClassName) + { + QMutexLocker locker(&mObjectGuard); + + if (!mLayoutRegistry.contains(rLayoutClassName)) + { + logger()->warn("Request for the creation of Layout with class '%1', which is not registered", rLayoutClassName); + return 0; + } + return mLayoutRegistry.value(rLayoutClassName)(); + } + + + void Factory::doRegisterAppender(const QString &rAppenderClassName, + AppenderFactoryFunc pAppenderFactoryFunc) + { + QMutexLocker locker(&mObjectGuard); + + if(rAppenderClassName.isEmpty()) + { + logger()->warn("Registering Appender factory function with empty class name"); + return; + } + mAppenderRegistry.insert(rAppenderClassName, pAppenderFactoryFunc); + } + + + void Factory::doRegisterFilter(const QString &rFilterClassName, + FilterFactoryFunc pFilterFactoryFunc) + { + QMutexLocker locker(&mObjectGuard); + + if(rFilterClassName.isEmpty()) + { + logger()->warn("Registering Filter factory function with empty class name"); + return; + } + mFilterRegistry.insert(rFilterClassName, pFilterFactoryFunc); + } + + + void Factory::doRegisterLayout(const QString &rLayoutClassName, + LayoutFactoryFunc pLayoutFactoryFunc) + { + QMutexLocker locker(&mObjectGuard); + + if(rLayoutClassName.isEmpty()) + { + logger()->warn("Registering Layout factory function with empty class name"); + return; + } + mLayoutRegistry.insert(rLayoutClassName, pLayoutFactoryFunc); + } + + + void Factory::doSetObjectProperty(QObject *pObject, + const QString &rProperty, + const QString &rValue) + { + // - Validate property + // - Get correct property name from meta object + // - Find specific property setter + // - If no specfifc propery setter can be found, + // find general property setter + // - Call property setter + + QMetaProperty meta_property; + if (!validateObjectProperty(meta_property, rProperty, pObject)) + return; + + QString property = QLatin1String(meta_property.name()); + QString type = QLatin1String(meta_property.typeName()); + logger()->debug("Setting property '%1' on object of class '%2' to value '%3'", + property, + QLatin1String(pObject->metaObject()->className()), + rValue); + + QVariant value; + bool ok = true; + if (type == QLatin1String("bool")) + value = OptionConverter::toBoolean(rValue, &ok); + else if (type == QLatin1String("int")) + value = OptionConverter::toInt(rValue, &ok); + else if (type == QLatin1String("qint64") || type == QLatin1String("qlonglong")) + value = OptionConverter::toQInt64(rValue, &ok); + else if (type == QLatin1String("Log4Qt::Level")) + value = QVariant::fromValue(OptionConverter::toLevel(rValue, &ok)); + else if (type == QLatin1String("QString")) + value = rValue; + else + { + LogError e = LOG4QT_ERROR(QT_TR_NOOP("Cannot convert to type '%1' for property '%2' on object of class '%3'"), + CONFIGURATOR_UNKNOWN_TYPE_ERROR, + "Log4Qt::Factory"); + e << type + << property + << QString::fromLatin1(pObject->metaObject()->className()); + logger()->error(e); + return; + } + if (!ok) + return; + + // Everything is checked and the type is the one of the property. + // Write should never return false + if (!meta_property.write(pObject, value)) + logger()->warn("Unxpected error result from QMetaProperty.write()"); + } + + + void Factory::doUnregisterAppender(const QString &rAppenderClassName) + { + QMutexLocker locker(&mObjectGuard); + + if (!mAppenderRegistry.contains(rAppenderClassName)) + { + logger()->warn("Request to unregister not registered Appender factory function for class '%1'", rAppenderClassName); + return; + } + mAppenderRegistry.remove(rAppenderClassName); + } + + + void Factory::doUnregisterFilter(const QString &rFilterClassName) + { + QMutexLocker locker(&mObjectGuard); + + if (!mFilterRegistry.contains(rFilterClassName)) + { + logger()->warn("Request to unregister not registered Filter factory function for class '%1'", rFilterClassName); + return; + } + mFilterRegistry.remove(rFilterClassName); + } + + + void Factory::doUnregisterLayout(const QString &rLayoutClassName) + { + QMutexLocker locker(&mObjectGuard); + + if (!mLayoutRegistry.contains(rLayoutClassName)) + { + logger()->warn("Request to unregister not registered Layout factory function for class '%1'", rLayoutClassName); + return; + } + mLayoutRegistry.remove(rLayoutClassName); + } + + + void Factory::registerDefaultAppenders() + { + mAppenderRegistry.insert(QLatin1String("org.apache.log4j.ConsoleAppender"), console_file_appender); + mAppenderRegistry.insert(QLatin1String("Log4Qt::ConsoleAppender"), console_file_appender); + mAppenderRegistry.insert(QLatin1String("org.apache.log4j.DailyRollingFileAppender"), create_daily_rolling_file_appender); + mAppenderRegistry.insert(QLatin1String("Log4Qt::DailyRollingFileAppender"), create_daily_rolling_file_appender); + mAppenderRegistry.insert(QLatin1String("org.apache.log4j.varia.DebugAppender"), create_debug_appender); + mAppenderRegistry.insert(QLatin1String("Log4Qt::DebugAppender"), create_debug_appender); + mAppenderRegistry.insert(QLatin1String("org.apache.log4j.FileAppender"), create_file_appender); + mAppenderRegistry.insert(QLatin1String("Log4Qt::FileAppender"), create_file_appender); + mAppenderRegistry.insert(QLatin1String("org.apache.log4j.varia.ListAppender"), create_list_appender); + mAppenderRegistry.insert(QLatin1String("Log4Qt::ListAppender"), create_list_appender); + mAppenderRegistry.insert(QLatin1String("org.apache.log4j.varia.NullAppender"), create_null_appender); + mAppenderRegistry.insert(QLatin1String("Log4Qt::NullAppender"), create_null_appender); + mAppenderRegistry.insert(QLatin1String("org.apache.log4j.RollingFileAppender"), create_rolling_file_appender); + mAppenderRegistry.insert(QLatin1String("Log4Qt::RollingFileAppender"), create_rolling_file_appender); + } + + + void Factory::registerDefaultFilters() + { + mFilterRegistry.insert(QLatin1String("org.apache.log4j.varia.DenyAllFilter"), create_deny_all_filter); + mFilterRegistry.insert(QLatin1String("Log4Qt::DenyAllFilter"), create_deny_all_filter); + mFilterRegistry.insert(QLatin1String("org.apache.log4j.varia.LevelMatchFilter"), create_level_match_filter); + mFilterRegistry.insert(QLatin1String("Log4Qt::LevelMatchFilter"), create_level_match_filter); + mFilterRegistry.insert(QLatin1String("org.apache.log4j.varia.LevelRangeFilter"), create_level_range_filter); + mFilterRegistry.insert(QLatin1String("Log4Qt::LevelRangeFilter"), create_level_range_filter); + mFilterRegistry.insert(QLatin1String("org.apache.log4j.varia.StringMatchFilter"), create_string_match_filter); + mFilterRegistry.insert(QLatin1String("Log4Qt::StringMatchFilter"), create_string_match_filter); + } + + + void Factory::registerDefaultLayouts() + { + mLayoutRegistry.insert(QLatin1String("org.apache.log4j.PatternLayout"), create_pattern_layout); + mLayoutRegistry.insert(QLatin1String("Log4Qt::PatternLayout"), create_pattern_layout); + mLayoutRegistry.insert(QLatin1String("org.apache.log4j.SimpleLayout"), create_simple_layout); + mLayoutRegistry.insert(QLatin1String("Log4Qt::SimpleLayout"), create_simple_layout); + mLayoutRegistry.insert(QLatin1String("org.apache.log4j.TTCCLayout"), create_ttcc_layout); + mLayoutRegistry.insert(QLatin1String("Log4Qt::TTCCLayout"), create_ttcc_layout); + } + + + bool Factory::validateObjectProperty(QMetaProperty &rMetaProperty, + const QString &rProperty, + QObject *pObject) + { + // Validate: + // - No null object pointer + // - No empty property name + // - Property exists on the object (QT or Java name) + // - Property is readable + // - Property is writable + + const char *p_context = "Log4Qt::Factory"; + LogError e = LOG4QT_ERROR(QT_TR_NOOP("Unable to set property value on object"), + CONFIGURATOR_PROPERTY_ERROR, + p_context); + + if (!pObject) + { + LogError ce = LOG4QT_ERROR(QT_TR_NOOP("Invalid null object pointer"), + 0, + p_context); + e.addCausingError(ce); + logger()->error(e); + return false; + } + if (rProperty.isEmpty()) + { + LogError ce = LOG4QT_ERROR(QT_TR_NOOP("Invalid empty property name"), + 0, + p_context); + e.addCausingError(ce); + logger()->error(e); + return false; + } + const QMetaObject *p_meta_object = pObject->metaObject(); + QString property = rProperty; + int i = p_meta_object->indexOfProperty(property.toLatin1()); + if (i < 0) + { + // Try name with lower case first character. Java properties names + // start upper case + property[0] = property[0].toLower(); + i = p_meta_object->indexOfProperty(property.toLatin1()); + if (i < 0) + { + LogError ce = LOG4QT_ERROR(QT_TR_NOOP("Property '%1' does not exist in class '%2'"), + 0, + p_context); + ce << property + << QString::fromLatin1(pObject->metaObject()->className()); + e.addCausingError(ce); + logger()->error(e); + return false; + } + } + rMetaProperty = p_meta_object->property(i); + if (!rMetaProperty.isWritable()) + { + LogError ce = LOG4QT_ERROR(QT_TR_NOOP("Property '%1' is not writable in class '%2'"), + 0, + p_context); + ce << property + << QString::fromLatin1(pObject->metaObject()->className()); + e.addCausingError(ce); + logger()->error(e); + return false; + } + + return true; + } + + + + /************************************************************************** + * Implementation: Operators, Helper + **************************************************************************/ + + +#ifndef QT_NO_DEBUG_STREAM + QDebug operator<<(QDebug debug, + const Factory &rFactory) + { + debug.nospace() << "Factory(" + << "appenderfactories:" << rFactory.registeredAppenders() + << "filterfactories:" << rFactory.registeredFilters() + << "layoutfactories:" << rFactory.registeredLayouts() + << ")"; + return debug.space(); + } +#endif // QT_NO_DEBUG_STREAM + + + +} // namespace Log4Qt + diff --git a/src/log4qt/src/log4qt/helpers/factory.h b/src/log4qt/src/log4qt/helpers/factory.h new file mode 100644 index 0000000..d654928 --- /dev/null +++ b/src/log4qt/src/log4qt/helpers/factory.h @@ -0,0 +1,492 @@ +/****************************************************************************** + * + * package: Log4Qt + * file: factory.h + * created: September 2007 + * author: Martin Heinrich + * + * + * Copyright 2007 Martin Heinrich + * + * 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. + * + ******************************************************************************/ + +#ifndef LOG4QT_HELPERS_FACTORY_H +#define LOG4QT_HELPERS_FACTORY_H + + +/****************************************************************************** + * Dependencies + ******************************************************************************/ + +#include +#include +#include + +QT_BEGIN_NAMESPACE +class QMetaProperty; +class QObject; +QT_END_NAMESPACE + +/****************************************************************************** + * Declarations + ******************************************************************************/ + +namespace Log4Qt +{ + + class Appender; + class Filter; + class Layout; + + /*! + * \brief The class Factory provides factories for Appender, Filter and + * Layout objects. + * + * The functions createAppender(), createFilter() and createLayout() + * allow to create objects by specifying their class names. By default + * all classes of the package are recognised with their Log4j and Log4Qt + * classanmes. For example an object of the class FileAppender can be + * craeted using "org.apache.log4j.FileAppender" or "Log4Qt::FileAppender". + * Additional classes can be registered using registerAppender(), + * registerFilter() and registerLayout(). + * + * An QObject property can be set from a string value with + * setObjectProperty(). The function handles the required error checking + * and type conversion. + * + * \note All the functions declared in this class are thread-safe. + * + * \sa PropertyConfigurator + */ + class Factory + { + public: + /*! + * Prototype for an Appender factory function. The function creates + * an Appender object on the heap and returns a pointer to it. + * + * \sa registerAppender(), createAppender() + */ + typedef Appender *(*AppenderFactoryFunc)(); + + /*! + * Prototype for a Filter factory function. The function creates + * a Filter object on the heap and returns a pointer to it. + * + * \sa registerFilter(), createFilter() + */ + typedef Filter *(*FilterFactoryFunc)(); + + /*! + * Prototype for a Layout factory function. The function creates + * a Layout object on the heap and returns a pointer to it. + * + * \sa registerLayout(), createLayout() + */ + typedef Layout *(*LayoutFactoryFunc)(); + + private: + Factory(); + Q_DISABLE_COPY(Factory) + + public: + /*! + * Creates an object for the class \a rAppenderClassName on the heap + * and returns a pointer to it. If the class has no registered factory + * function a null pointer is returned. + * + * \sa registerAppender(), unregisterAppender(), registeredAppenders() + */ + static Appender *createAppender(const QString &rAppenderClassName); + + /*! + * This is an overloaded member function, provided for convenience. + */ + static Appender *createAppender(const char *pAppenderClassName); + + /*! + * Creates an object for the class \a rFilterClassName on the heap + * and returns a pointer to it. If the class has no registered factory + * function a null pointer is returned. + * + * \sa registerFilter(), unregisterFilter(), registeredFilters() + */ + static Filter *createFilter(const QString &rFilterClassName); + + /*! + * This is an overloaded member function, provided for convenience. + */ + static Filter *createFilter(const char *pFilterClassName); + + /*! + * Creates an object for the class \a rLayoutClassName on the heap + * and returns a pointer to it. If the class has no registered factory + * function a null pointer is returned. + * + * \sa registerLayout(), unregisterLayout(), registeredLayouts() + */ + static Layout *createLayout(const QString &rLayoutClassName); + + /*! + * This is an overloaded member function, provided for convenience. + */ + static Layout *createLayout(const char *pLayoutClassName); + + /*! + * Returns the Factory instance. + */ + static Factory *instance(); + + /*! + * Registers the Appender factory function \a pAppenderFactoryFunc + * for the class \a rAppenderClassName. If a registered factory + * function exists for the class, it is replaced with + * \a pAppenderFactoryFunc. + * + * \sa unregisterAppender(), registeredAppenders(), createAppender() + */ + static void registerAppender(const QString &rAppenderClassName, + AppenderFactoryFunc pAppenderFactoryFunc); + + /*! + * This is an overloaded member function, provided for convenience. + */ + static void registerAppender(const char *pAppenderClassName, + AppenderFactoryFunc pAppenderFactoryFunc); + + /*! + * Registers the Filter factory function \a pFilterFactoryFunc + * for the class \a rFilterClassName. If a registered factory + * function exists for the class, it is replaced with + * \a pFilterFactoryFunc. + * + * \sa unregisterFilter(), registeredFilters(), createFilter() + */ + static void registerFilter(const QString &rFilterClassName, + FilterFactoryFunc pFilterFactoryFunc); + + /*! + * This is an overloaded member function, provided for convenience. + */ + static void registerFilter(const char *pFilterClassName, + FilterFactoryFunc pFilterFactoryFunc); + + /*! + * Registers the Layout factory function \a pLayoutFactoryFunc + * for the class \a rLayoutClassName. If a registered factory + * function exists for the class, it is replaced with + * \a pLayoutFactoryFunc. + * + * \sa unregisterLayout(), registeredLayout(), createLayout() + */ + static void registerLayout(const QString &rLayoutClassName, + LayoutFactoryFunc pLayoutFactoryFunc); + + /*! + * This is an overloaded member function, provided for convenience. + */ + static void registerLayout(const char *pLayoutClassName, + LayoutFactoryFunc pLayoutFactoryFunc); + + /*! + * Returns a list of the class names for registered Appender factory + * functions. + * + * \sa registerAppender(), unregisterAppender() + */ + static QStringList registeredAppenders(); + + /*! + * Returns a list of the class names for registered Filter factory + * functions. + * + * \sa registerFilter(), unregisterFilter() + */ + static QStringList registeredFilters(); + + /*! + * Returns a list of the class names for registered Layout factory + * functions. + * + * \sa registerLayout(), unregisterLayout() + */ + static QStringList registeredLayouts(); + + /*! + * Sets the property \a rProperty of the object \a pObject to the + * value \a rValue. The function will test that the property + * \a rProperty is writeable and of a type the function can convert to. + * The types bool, int, Level and QString are supported. + * + * \sa OptionConverter + */ + static void setObjectProperty(QObject *pObject, + const QString &rProperty, + const QString &rValue); + + /*! + * This is an overloaded member function, provided for convenience. + */ + static void setObjectProperty(QObject *pObject, + const char *pProperty, + const QString &rValue); + + /*! + * Unregisters the Appender factory function for the class + * \a rAppenderClassName. + * + * \sa registerAppender(), registeredAppenders() + */ + static void unregisterAppender(const QString &rAppenderClassName); + + /*! + * This is an overloaded member function, provided for convenience. + */ + static void unregisterAppender(const char *pAppenderClassName); + + /*! + * Unregisters the Filter factory function for the class + * \a rFilterClassName. + * + * \sa registerFilter(), registeredFilters() + */ + static void unregisterFilter(const QString &rFilterClassName); + + /*! + * This is an overloaded member function, provided for convenience. + */ + static void unregisterFilter(const char *pFilterClassName); + + /*! + * Unregisters the Layout factory function for the class + * \a rLayoutClassName. + * + * \sa registerLayout(), registeredLayouts() + */ + static void unregisterLayout(const QString &rLayoutClassName); + + /*! + * This is an overloaded member function, provided for convenience. + */ + static void unregisterLayout(const char *pLayoutClassName); + + private: + Appender *doCreateAppender(const QString &rAppenderClassName); + Filter *doCreateFilter(const QString &rFilterClassName); + Layout *doCreateLayout(const QString &rLayoutClassName); + void doRegisterAppender(const QString &rAppenderClassName, + AppenderFactoryFunc pAppenderFactoryFunc); + void doRegisterFilter(const QString &rFilterClassName, + FilterFactoryFunc pFilterFactoryFunc); + void doRegisterLayout(const QString &rLayoutClassName, + LayoutFactoryFunc pLayoutFactoryFunc); + void doSetObjectProperty(QObject *pObject, + const QString &rProperty, + const QString &rValue); + void doUnregisterAppender(const QString &rAppenderClassName); + void doUnregisterFilter(const QString &rFilterClassName); + void doUnregisterLayout(const QString &rLayoutClassName); + void registerDefaultAppenders(); + void registerDefaultFilters(); + void registerDefaultLayouts(); + bool validateObjectProperty(QMetaProperty &rMetaProperty, + const QString &rProperty, + QObject *pObject); + + private: + mutable QMutex mObjectGuard; + QHash mAppenderRegistry; + QHash mFilterRegistry; + QHash mLayoutRegistry; + }; + + + /************************************************************************** + * Operators, Helper + **************************************************************************/ + +#ifndef QT_NO_DEBUG_STREAM + /*! + * \relates Factory + * + * Writes all object member variables to the given debug stream \a rDebug and + * returns the stream. + * + * + * %Factory(appenderfactories:("Log4Qt::DebugAppender", "Log4Qt::NullAppender", + * "Log4Qt::ConsoleAppender", "org.apache.log4j.varia.DebugAppender", + * "org.apache.log4j.FileAppender", "org.apache.log4j.RollingFileAppender", + * "org.apache.log4j.DailyRollingFileAppender", + * "org.apache.log4j.varia.ListAppender", + * "org.apache.log4j.varia.NullAppender", + * "Log4Qt::FileAppender", "org.apache.log4j.ConsoleAppender", + * "Log4Qt::DailyRollingFileAppender", "Log4Qt::ListAppender", + * "Log4Qt::RollingFileAppender") filterfactories: + * ("Log4Qt::DenyAllFilter", "Log4Qt::StringMatchFilter", + * "Log4Qt::LevelRangeFilter", "org.apache.log4j.varia.DenyAllFilter", + * "org.apache.log4j.varia.LevelRangeFilter", + * "org.apache.log4j.varia.StringMatchFilter", "Log4Qt::LevelMatchFilter", + * "org.apache.log4j.varia.LevelMatchFilter") layoutfactories: + * ("org.apache.log4j.SimpleLayout", "Log4Qt::PatternLayout", + * "Log4Qt::SimpleLayout", "org.apache.log4j.TTCCLayout", + * "Log4Qt::TTCCLayout", "org.apache.log4j.PatternLayout") ) + * + * \sa QDebug, Factory::logManager() + */ + QDebug operator<<(QDebug debug, + const Factory &rFactory); +#endif // QT_NO_DEBUG_STREAM + + + + /************************************************************************** + * Inline + **************************************************************************/ + + inline Appender *Factory::createAppender(const QString &rAppenderClassName) + { + return instance()->doCreateAppender(rAppenderClassName); + } + + inline Appender *Factory::createAppender(const char *pAppenderClassName) + { + return instance()->doCreateAppender(QLatin1String(pAppenderClassName)); + } + + inline Filter *Factory::createFilter(const QString &rFilterClassName) + { + return instance()->doCreateFilter(rFilterClassName); + } + + inline Filter *Factory::createFilter(const char *pFilterClassName) + { + return instance()->doCreateFilter(QLatin1String(pFilterClassName)); + } + + inline Layout *Factory::createLayout(const QString &rLayoutClassName) + { + return instance()->doCreateLayout(rLayoutClassName); + } + + inline Layout *Factory::createLayout(const char *pLayoutClassName) + { + return instance()->doCreateLayout(QLatin1String(pLayoutClassName)); + } + + inline void Factory::registerAppender(const QString &rAppenderClassName, + AppenderFactoryFunc pAppenderFactoryFunc) + { + instance()->doRegisterAppender(rAppenderClassName, pAppenderFactoryFunc); + } + + inline void Factory::registerAppender(const char *pAppenderClassName, + AppenderFactoryFunc pAppenderFactoryFunc) + { + instance()->doRegisterAppender(QLatin1String(pAppenderClassName), pAppenderFactoryFunc); + } + + inline void Factory::registerFilter(const QString &rFilterClassName, + FilterFactoryFunc pFilterFactoryFunc) + { + instance()->doRegisterFilter(rFilterClassName, pFilterFactoryFunc); + } + + inline void Factory::registerFilter(const char *pFilterClassName, + FilterFactoryFunc pFilterFactoryFunc) + { + instance()->doRegisterFilter(QLatin1String(pFilterClassName), pFilterFactoryFunc); + } + + inline void Factory::registerLayout(const QString &rLayoutClassName, + LayoutFactoryFunc pLayoutFactoryFunc) + { + instance()->doRegisterLayout(rLayoutClassName, pLayoutFactoryFunc); + } + + inline void Factory::registerLayout(const char *pLayoutClassName, + LayoutFactoryFunc pLayoutFactoryFunc) + { + instance()->doRegisterLayout(QLatin1String(pLayoutClassName), pLayoutFactoryFunc); + } + + inline QStringList Factory::registeredAppenders() + { + QMutexLocker locker(&instance()->mObjectGuard); + return instance()->mAppenderRegistry.keys(); + } + + inline QStringList Factory::registeredFilters() + { + QMutexLocker locker(&instance()->mObjectGuard); + return instance()->mFilterRegistry.keys(); + } + + inline QStringList Factory::registeredLayouts() + { + QMutexLocker locker(&instance()->mObjectGuard); + return instance()->mLayoutRegistry.keys(); + } + + inline void Factory::setObjectProperty(QObject *pObject, + const QString &rProperty, + const QString &rValue) + { + instance()->doSetObjectProperty(pObject, rProperty, rValue); + } + + inline void Factory::setObjectProperty(QObject *pObject, + const char *pProperty, + const QString &rValue) + { + instance()->doSetObjectProperty(pObject, QLatin1String(pProperty), rValue); + } + + inline void Factory::unregisterAppender(const QString &rAppenderClassName) + { + instance()->doUnregisterAppender(rAppenderClassName); + } + + inline void Factory::unregisterAppender(const char *pAppenderClassName) + { + instance()->doUnregisterAppender(QLatin1String(pAppenderClassName)); + } + + inline void Factory::unregisterFilter(const QString &rFilterClassName) + { + instance()->doUnregisterFilter(rFilterClassName); + } + + inline void Factory::unregisterFilter(const char *pFilterClassName) + { + instance()->doUnregisterFilter(QLatin1String(pFilterClassName)); + } + + inline void Factory::unregisterLayout(const QString &rLayoutClassName) + { + instance()->doUnregisterLayout(rLayoutClassName); + } + + inline void Factory::unregisterLayout(const char *pLayoutClassName) + { + instance()->doUnregisterLayout(QLatin1String(pLayoutClassName)); + } + +} // namespace Log4Qt + + +// Q_DECLARE_TYPEINFO(Log4Qt::Factory, Q_COMPLEX_TYPE); // use default + + +#endif // LOG4QT_HELPERS_FACTORY_H diff --git a/src/log4qt/src/log4qt/helpers/initialisationhelper.cpp b/src/log4qt/src/log4qt/helpers/initialisationhelper.cpp new file mode 100644 index 0000000..e8ba59b --- /dev/null +++ b/src/log4qt/src/log4qt/helpers/initialisationhelper.cpp @@ -0,0 +1,185 @@ +/****************************************************************************** + * + * package: Log4Qt + * file: initialisationhelper.cpp + * created: September 2007 + * author: Martin Heinrich + * + * + * changes Feb 2009, Martin Heinrich + * - Fixed VS 2008 unreferenced formal parameter warning by using + * Q_UNUSED in operator<<. + * + * + * Copyright 2007 - 2009 Martin Heinrich + * + * 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. + * + ******************************************************************************/ + + + +/****************************************************************************** + * Dependencies + ******************************************************************************/ + + +#include "log4qt/helpers/initialisationhelper.h" + +#include +#include +#include +#include +#include +#ifndef QT_NO_DATASTREAM +#include +#endif +#include "log4qt/helpers/datetime.h" +#include "log4qt/helpers/logerror.h" +#include "log4qt/loggingevent.h" + + + +namespace Log4Qt +{ + + + /************************************************************************** + *Declarations + **************************************************************************/ + + + + /************************************************************************** + * C helper functions + **************************************************************************/ + + + + /************************************************************************** + * Class implementation: InitialisationHelper + **************************************************************************/ + + + InitialisationHelper::InitialisationHelper() : + mStartTime(DateTime::currentDateTime().toMilliSeconds()), + mEnvironmentSettings() + { + doRegisterTypes(); + doInitialiseEnvironmentSettings(); + } + + + InitialisationHelper::~InitialisationHelper() + { + Q_ASSERT_X(false, "InitialisationHelper::~InitialisationHelper()", "Unexpected destruction of singleton object"); + } + + + LOG4QT_IMPLEMENT_INSTANCE(InitialisationHelper) + + + void InitialisationHelper::doInitialiseEnvironmentSettings() + { + // Is Process::systemEnvironment() safe to be used before a QCoreApplication + // object has been created? + + QStringList setting_keys; + setting_keys << QLatin1String("Debug"); + setting_keys << QLatin1String("DefaultInitOverride"); + setting_keys << QLatin1String("Configuration"); + setting_keys << QLatin1String("ConfiguratorClass"); + + QHash env_keys; + QString entry; + Q_FOREACH(entry, setting_keys) + env_keys.insert(QString::fromLatin1("log4qt_").append(entry).toUpper(), entry); + + QStringList sys_env = QProcess::systemEnvironment(); + Q_FOREACH(entry, sys_env) + { + int i = entry.indexOf(QLatin1Char('=')); + if (i == -1) + continue; + QString key = entry.left(i); + QString value = entry.mid(i + 1).trimmed(); + if (env_keys.contains(key)) + mEnvironmentSettings.insert(env_keys.value(key), value); + } + } + + + void InitialisationHelper::doRegisterTypes() + { + qRegisterMetaType("Log4Qt::LogError"); + qRegisterMetaType("Log4Qt::Level"); + qRegisterMetaType("Log4Qt::LoggingEvent"); + + #ifndef QT_NO_DATASTREAM + qRegisterMetaTypeStreamOperators("Log4Qt::LogError"); + qRegisterMetaTypeStreamOperators("Log4Qt::Level"); + qRegisterMetaTypeStreamOperators("Log4Qt::LoggingEvent"); + #endif + } + + + QString InitialisationHelper::doSetting(const QString &rKey, + const QString &rDefault) const + { + if (mEnvironmentSettings.contains(rKey)) + return mEnvironmentSettings.value(rKey); + + if (QCoreApplication::instance()) + { + QSettings s; + s.beginGroup(QLatin1String("Log4Qt")); + return s.value(rKey, rDefault).toString().trimmed(); + } + else + return rDefault; + } + + + bool InitialisationHelper::staticInitialisation() + { + instance(); + return true; + } + + + bool InitialisationHelper::msStaticInitialisation = staticInitialisation(); + + + + /************************************************************************** + * Implementation: Operators, Helper + **************************************************************************/ + + +#ifndef QT_NO_DEBUG_STREAM + QDebug operator<<(QDebug debug, + const InitialisationHelper &rInitialisationHelper) + { + Q_UNUSED(rInitialisationHelper); + debug.nospace() << "InitialisationHelper(" + << "starttime:" << InitialisationHelper::startTime() + << "(" << DateTime::fromMilliSeconds(InitialisationHelper::startTime()) << ")" + << "environmentsettings:" << InitialisationHelper::environmentSettings() + << ")"; + return debug.space(); + } +#endif // QT_NO_DEBUG_STREAM + + + +} // namespace Log4Qt diff --git a/src/log4qt/src/log4qt/helpers/initialisationhelper.h b/src/log4qt/src/log4qt/helpers/initialisationhelper.h new file mode 100644 index 0000000..95b370d --- /dev/null +++ b/src/log4qt/src/log4qt/helpers/initialisationhelper.h @@ -0,0 +1,435 @@ +/****************************************************************************** + * + * package: Log4Qt + * file: initialisationhelper.h + * created: September 2007 + * author: Martin Heinrich + * + * + * changes: Sep 2008, Martin Heinrich: + * - Replaced usage of q_atomic_test_and_set_ptr with + * QBasicAtomicPointer + * + * + * Copyright 2007 - 2008 Martin Heinrich + * + * 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. + * + ******************************************************************************/ + +#ifndef LOG4QT_HELPERS_INITIALISATIONHELPER_H +#define LOG4QT_HELPERS_INITIALISATIONHELPER_H + + +/****************************************************************************** + * Dependencies + ******************************************************************************/ + +#include +#include +#include + +#if QT_VERSION >= QT_VERSION_CHECK(4, 4, 0) +# ifndef Q_ATOMIC_POINTER_TEST_AND_SET_IS_ALWAYS_NATIVE +# warning "QAtomicPointer test and set is not native. The macros Log4Qt::LOG4QT_GLOBAL_STATIC and Log4Qt::LOG4QT_IMPLEMENT_INSTANCE are not thread-safe." +# endif +#endif + + +/****************************************************************************** + * Declarations + ******************************************************************************/ + +class QMutex; + +namespace Log4Qt +{ + /*! + * LOG4QT_GLOBAL_STATIC declares a static function \a FUNCTION that + * returns a pointer to a singleton object of the type \a TYPE. + * + * The macro uses a static variable to store a pointer to the singleton + * object. On the first invocation an object of the type \a TYPE is created + * on the heap and the pointer is set. Any further invocations will return + * the stored pointer. If multiple threads are accessing the function + * without the pointer being set, each thread will create an object of the + * type \a TYPE. The threads that find the pointer already been set will + * delete their object. The singleton object will not be deleted during static + * de-initialisation. + * + * The following example uses a global global mutex object to synchronise + * access to a static member variable. + * + * \code + * #file: myclass.h + * + * class MyClass + * { + * public: + * MyClass(); + * ~MyClass(); + * private: + * static qint64 msObjectCount; + * } + * \endcode + * \code + * #file: myclass.cpp + * + * #include myclass.h + * + * LOG4QT_GLOBAL_STATIC(QMutex, class_guard) + * + * MyClass::MyClass() + * { + * QMutexLocker(class_guard()); + * msObjectCount++; + * } + * + * MyClass::~MyClass() + * { + * QMutexLocker(class_guard()); + * msObjectCount--; + * } + * + * qint64 MyClass::msObjectCount = 0; + * \endcode + * + * \note The function created by the macro is thread-safe. + * + * \sa \ref Log4Qt::LOG4QT_IMPLEMENT_INSTANCE "LOG4QT_IMPLEMENT_INSTANCE", + * \ref Log4Qt::InitialisationHelper "InitialisationHelper" + */ +#if QT_VERSION < QT_VERSION_CHECK(4, 4, 0) + #define LOG4QT_GLOBAL_STATIC(TYPE, FUNCTION) \ + static volatile TYPE *sp_global_static_##FUNCTION = 0; \ + TYPE *FUNCTION() \ + { \ + if (!sp_global_static_##FUNCTION) \ + { \ + TYPE *p_temp = new TYPE; \ + if (!q_atomic_test_and_set_ptr(&sp_global_static_##FUNCTION, \ + 0, p_temp)) \ + delete p_temp; \ + } \ + return const_cast(sp_global_static_##FUNCTION); \ + } +#elif QT_VERSION < QT_VERSION_CHECK(5, 0, 0) + #define LOG4QT_GLOBAL_STATIC(TYPE, FUNCTION) \ + static QBasicAtomicPointer sp_global_static_##FUNCTION = \ + Q_BASIC_ATOMIC_INITIALIZER(0); \ + TYPE *FUNCTION() \ + { \ + if (!sp_global_static_##FUNCTION) \ + { \ + TYPE *p_temp = new TYPE; \ + if (!sp_global_static_##FUNCTION.testAndSetOrdered(0, \ + p_temp)) \ + delete p_temp; \ + } \ + return sp_global_static_##FUNCTION; \ + } +#else + #define LOG4QT_GLOBAL_STATIC(TYPE, FUNCTION) \ + static QBasicAtomicPointer sp_global_static_##FUNCTION = \ + Q_BASIC_ATOMIC_INITIALIZER(0); \ + TYPE *FUNCTION() \ + { \ + if (!sp_global_static_##FUNCTION.loadAcquire()) \ + { \ + TYPE *p_temp = new TYPE; \ + if (!sp_global_static_##FUNCTION.testAndSetOrdered(0, \ + p_temp)) \ + delete p_temp; \ + } \ + return sp_global_static_##FUNCTION.loadAcquire(); \ + } +#endif + + /*! + * LOG4QT_IMPLEMENT_INSTANCE implements an instance function for a + * singleton class \a TYPE. + * + * The function works like the one created by + * \ref Log4Qt::LOG4QT_GLOBAL_STATIC "LOG4QT_GLOBAL_STATIC". + * + * The following example illustrates how to use the macro to create a + * singleton class: + * + * \code + * #file: mysingleton.h + * + * class MySingleton + * { + * private: + * MySingleton(); + * ~MySingleton(); + * public: + * MySingleton *instance(); + * } + * \endcode + * \code + * #file: mysingleton.cpp + * + * #include mysingleton.h + * + * MySingleton::MySingleton() + * {} + * + * MySingleton::~MySingleton() + * {} + * + * LOG4QT_IMPLEMENT_INSTANCE(MySingleton) + * + * \endcode + * + * \note The function created by the macro is thread-safe. + * + * \sa \ref Log4Qt::LOG4QT_GLOBAL_STATIC "LOG4QT_GLOBAL_STATIC", + * \ref Log4Qt::InitialisationHelper "InitialisationHelper" + */ +#if QT_VERSION < QT_VERSION_CHECK(4, 4, 0) + #define LOG4QT_IMPLEMENT_INSTANCE(TYPE) \ + static TYPE *sp_singleton_##TYPE = 0; \ + TYPE *TYPE::instance() \ + { \ + if (!sp_singleton_##TYPE) \ + { \ + TYPE *p_temp = new TYPE; \ + if (!q_atomic_test_and_set_ptr(&sp_singleton_##TYPE, \ + 0, p_temp)) \ + delete p_temp; \ + } \ + return sp_singleton_##TYPE; \ + } +#elif QT_VERSION < QT_VERSION_CHECK(5, 0, 0) + #define LOG4QT_IMPLEMENT_INSTANCE(TYPE) \ + static QBasicAtomicPointer sp_singleton_##TYPE = \ + Q_BASIC_ATOMIC_INITIALIZER(0); \ + TYPE *TYPE::instance() \ + { \ + if (!sp_singleton_##TYPE) \ + { \ + TYPE *p_temp = new TYPE; \ + if (!sp_singleton_##TYPE.testAndSetOrdered(0, p_temp)) \ + delete p_temp; \ + } \ + return sp_singleton_##TYPE; \ + } +#else + #define LOG4QT_IMPLEMENT_INSTANCE(TYPE) \ + static QBasicAtomicPointer sp_singleton_##TYPE = \ + Q_BASIC_ATOMIC_INITIALIZER(0); \ + TYPE *TYPE::instance() \ + { \ + if (!sp_singleton_##TYPE.loadAcquire()) \ + { \ + TYPE *p_temp = new TYPE; \ + if (!sp_singleton_##TYPE.testAndSetOrdered(0, p_temp)) \ + delete p_temp; \ + } \ + return sp_singleton_##TYPE.loadAcquire(); \ + } +#endif + + /*! + * \brief The class InitialisationHelper performs static initialisation + * tasks. + * + * The InitialisationHelper is either created on the first call or through + * static initialisation. It will capture the programs startup time, + * which can be retrieved using startTime(). The system environment + * is analysed for package related definitions. The result is available + * over environmentSettings(). The packages custom types are registered with + * the Qt type system. + * + * Settings for the package can be retrieved using setting(). Two macros + * are available to help with the creation of singletons / global static + * objects (\ref Log4Qt::LOG4QT_GLOBAL_STATIC "LOG4QT_GLOBAL_STATIC" and + * \ref Log4Qt::LOG4QT_IMPLEMENT_INSTANCE "LOG4QT_IMPLEMENT_INSTANCE"). + * + * \note All the functions declared in this class are thread-safe. + * + * \sa \ref Init "Initialization procedure", + */ + class InitialisationHelper + { + private: + InitialisationHelper(); + InitialisationHelper(const InitialisationHelper &rOther); // Not implemented + virtual ~InitialisationHelper(); + InitialisationHelper &operator=(const InitialisationHelper &rOther); // Not implemented + + public: + + /*! + * Returns a hash with the settings retrieved from the system + * environment on startup. + * + * The following table shows the environment variables taken into + * account and the setting key used for them. + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + *
Environment variable Setting key
LOG4QT_DEBUG Debug
LOG4QT_DEFAULTINITOVERRIDE DefaultInitOverride
LOG4QT_CONFIGURATION Configuration
LOG4QT_CONFIGURATORCLASS ConfiguratorClass
+ * + * \sa \ref Env "Environment Variables", + * setting() + */ + static QHash environmentSettings(); + + /*! + * Returns the InitialisationHelper instance. + */ + static InitialisationHelper *instance(); + + /*! + * Returns the value for the setting \a rKey or \a rDefault, if it is + * not defined. + * + * A setting can be either defined by an environment variable or by a + * key in the application setting. The function will first test the + * settings made by environment variables for the key \a rKey using + * environmentSettings(). If the key is not present and a + * QCoreApplication exists, the application settings are tested for + * the key \a rKey in the group \c %Log4Qt. + * + * The following setting exists: + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + *
Setting key Description
Debug The variable controls the Level value for the logger + * LogManager::logLogger(). If the value is a valid Level string, + * the level for the logger is set to the level. If the value is not + * a valid Level string, \ref Level::DEBUG_INT "DEBUG_INT" is used. + * Otherwise \ref Level::ERROR_INT "ERROR_INT" is used.
DefaultInitOverride The variable controls the \ref Init "initialization procedure" + * performed by the \ref LogManager "LogManager" on startup. + * If it is set to any other value then \c false the \ref Init + * "initialization procedure" is skipped.
Configuration Specifies the configuration file used for initialising the package.
ConfiguratorClass Specifies the configurator class used for initialising the package.
+ * + * \sa environmentSettings(), \ref Env "Environment Variables", + * \ref Init "Initialization procedure", + * LogManager::configureLogLogger(), LogManager::startup() + */ + static QString setting(const QString &rKey, + const QString &rDefault = QString()); + + /*! + * Returns the start time of the program as the number of milliseconds + * that have passed since 1970-01-01T00:00:00,000, Coordinated + * Universal Time (Qt::UTC). + * + * \sa DateTime::fromMilliSeconds(), + * DateTime::toMilliSeconds() + */ + static qint64 startTime(); + + private: + void doInitialiseEnvironmentSettings(); + void doRegisterTypes(); + QString doSetting(const QString &rKey, + const QString &rDefault) const; + static bool shutdown(); + static bool staticInitialisation(); + + private: + // QMutex mObjectGuard; + const qint64 mStartTime; + QHash mEnvironmentSettings; + static bool msStaticInitialisation; + +#ifndef QT_NO_DEBUG_STREAM + // Needs to be friend to access details + friend QDebug operator<<(QDebug debug, + const InitialisationHelper &rInitialisationHelper); +#endif // QT_NO_DEBUG_STREAM + }; + + + /************************************************************************** + * Operators, Helper + **************************************************************************/ + +#ifndef QT_NO_DEBUG_STREAM + /*! + * \relates InitialisationHelper + * + * Writes all object member variables to the given debug stream \a rDebug and + * returns the stream. + * + * + * %InitialisationHelper(InitialisationHelper(starttime:1193883677438( + * QDateTime("Wed Oct 31 21:21:17 2007") ) + * environmentsettings: QHash(("configuration", "\myapp.log4j") + * ("Debug", "DEBUG")) ) ) + * + * \sa QDebug, InitialisationHelper::logManager() + */ + QDebug operator<<(QDebug debug, + const InitialisationHelper &rInitialisationHelper); +#endif // QT_NO_DEBUG_STREAM + + + /************************************************************************** + * Inline + **************************************************************************/ + + inline QHash InitialisationHelper::environmentSettings() + { // QMutexLocker locker(&instance()->mObjectGuard); // Constant for object lifetime + return instance()->mEnvironmentSettings; } + + inline QString InitialisationHelper::setting(const QString &rKey, + const QString &rDefault) + { // QMutexLocker locker(&instance()->mObjectGuard); // Reentrant and const + return instance()->doSetting(rKey, rDefault); } + + inline qint64 InitialisationHelper::startTime() + { // QMutexLocker locker(&instance()->mObjectGuard); // Constant for object lifetime + return instance()->mStartTime; } + +} // namespace Log4Qt + + +// Q_DECLARE_TYPEINFO(Log4Qt::InitialisationHelper, Q_COMPLEX_TYPE); // use default + + +#endif // LOG4QT_HELPERS_INITIALISATIONHELPER_H diff --git a/src/log4qt/src/log4qt/helpers/logerror.cpp b/src/log4qt/src/log4qt/helpers/logerror.cpp new file mode 100644 index 0000000..f78d2ab --- /dev/null +++ b/src/log4qt/src/log4qt/helpers/logerror.cpp @@ -0,0 +1,354 @@ +/****************************************************************************** + * + * package: Log4Qt + * file: logerror.cpp + * created: September 2007 + * author: Martin Heinrich + * + * + * Copyright 2007 Martin Heinrich + * + * 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. + * + ******************************************************************************/ + + + +/****************************************************************************** + * Dependencies + *****************************************************************************/ + + +#include "log4qt/helpers/logerror.h" + +#include +#include +#include +#include +#include +#include +#include +#include "log4qt/helpers/initialisationhelper.h" + + +namespace Log4Qt +{ + + + /************************************************************************** + * Declarations + **************************************************************************/ + + + typedef QThreadStorage ThreadError; + + + + /************************************************************************** + * C helper functions + **************************************************************************/ + + + LOG4QT_GLOBAL_STATIC(ThreadError, thread_error) + + + + /************************************************************************** + * Class implementation: LogError + **************************************************************************/ + + + LogError::LogError() : + mCode(0), + mContext(), + mMessage(), + mSymbol(), + mArgs(), + mCausingErrors() + { + } + + + LogError::LogError(const QString &rMessage, + int code, + const QString &rSymbol, + const QString &rContext) : + mCode(code), + mContext(rContext), + mMessage(cleanMessage(rMessage)), + mSymbol(rSymbol), + mArgs(), + mCausingErrors() + { + } + + + LogError::LogError(const char *pMessage, + int code, + const char *pSymbol, + const char *pContext, + Encoding encoding) : + mCode(code), + mContext(QString::fromLatin1(pContext)), + mMessage(), + mSymbol(QString::fromLatin1(pSymbol)), + mArgs(), + mCausingErrors() + { + switch(encoding) + { + case LATIN1: + mMessage = QString::fromLatin1(pMessage); + break; + case CODECFORTR: +#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0) + mMessage = QTextCodec::codecForTr()->toUnicode(pMessage); +#else + mMessage = QString::fromUtf8(pMessage); +#endif + break; + case UNICODEUTF8: + mMessage = QString::fromUtf8(pMessage); + break; + default: + Q_ASSERT_X(false, "LogError::LogError", "Unkown encoding constant"); + mMessage = QString::fromLatin1(pMessage); + } + mMessage = cleanMessage(mMessage); + + if (mSymbol == QString::number(mCode)) + mSymbol.clear(); + } + + + QString LogError::translatedMessage() const + { +#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0) + return QCoreApplication::translate(mContext.toLatin1(), mMessage.toUtf8().data(), 0, QCoreApplication::UnicodeUTF8); +#else + return QCoreApplication::translate(mContext.toLatin1(), mMessage.toUtf8().data(), 0); +#endif + } + + + LogError LogError::lastError() + { + if (!thread_error()->hasLocalData()) + return LogError(); + else + return *thread_error()->localData(); + } + + + void LogError::setLastError(const LogError &rLogError) + { + if (!thread_error()->hasLocalData()) + thread_error()->setLocalData(new LogError); + + *thread_error()->localData() = rLogError; + } + + + QString LogError::toString() const + { + QString result = messageWithArgs(); + + QString context_symbol = mContext; + if (!context_symbol.isEmpty() && !mSymbol.isEmpty()) + context_symbol.append(QLatin1String("::")); + context_symbol.append(mSymbol); + + if (!context_symbol.isEmpty() || mCode) + { + result.append(QLatin1String(" (")); + if (!context_symbol.isEmpty()) + result.append(context_symbol); + if (!context_symbol.isEmpty() && mCode) + result.append(QLatin1String(", ")); + if (mCode) + result.append(QString::number(mCode)); + result.append(QLatin1String(")")); + } + + if (!mCausingErrors.isEmpty()) + { + QString causing_errors_str = QLatin1String(": ") + mCausingErrors.at(0).toString(); + int i = 1; + while (i < mCausingErrors.count()) + { + causing_errors_str.append(QLatin1String(", ")).append(mCausingErrors.at(i).toString()); + i++; + } + result.append(causing_errors_str); + } + + return result; + } + + + QString LogError::insertArgs(const QString &rMessage) const + { + QString result; + + /* + + // Don't use a loop to be able to handle arguments that conatin strings + // like %1. + // Using this method only 9 arguments can be handled as the %1 + // in %11 gets also replaced with the first argument. + + switch (mArgs.count()) + { + case 0: + break; + case 1: + result = rMessage.arg(mArgs.at(0)); + break; + case 2: + result = rMessage.arg(mArgs.at(0), mArgs.at(1)); + break; + case 3: + result = rMessage.arg(mArgs.at(0), mArgs.at(1), mArgs.at(2)); + break; + case 4: + result = rMessage.arg(mArgs.at(0), mArgs.at(1), mArgs.at(2), mArgs.at(3)); + break; + case 5: + result = rMessage.arg(mArgs.at(0), mArgs.at(1), mArgs.at(2), mArgs.at(3), mArgs.at(4)); + break; + case 6: + result = rMessage.arg(mArgs.at(0), mArgs.at(1), mArgs.at(2), mArgs.at(3), mArgs.at(4), mArgs.at(5)); + break; + case 7: + result = rMessage.arg(mArgs.at(0), mArgs.at(1), mArgs.at(2), mArgs.at(3), mArgs.at(4), mArgs.at(5), mArgs.at(6)); + break; + case 8: + result = rMessage.arg(mArgs.at(0), mArgs.at(1), mArgs.at(2), mArgs.at(3), mArgs.at(4), mArgs.at(5), mArgs.at(6), mArgs.at(7)); + break; + default: + result = rMessage.arg(mArgs.at(0), mArgs.at(1), mArgs.at(2), mArgs.at(3), mArgs.at(4), mArgs.at(5), mArgs.at(6), mArgs.at(7), mArgs.at(8)); + break; + } + + if (mArgs.count() > 9) + { + int i = 9; + while(i < mArgs.count()) + { + result = result.arg(mArgs.at(i)); + i++; + } + } + */ + + result = rMessage; + QVariant arg; + Q_FOREACH(arg, mArgs) + result = result.arg(arg.toString()); + return result; + } + + + QString LogError::cleanMessage(const QString &rMessage) + { + if (rMessage.isEmpty()) + return rMessage; + + QString result = rMessage; + if (rMessage.at(rMessage.size() - 1) == QLatin1Char('.')) + result = rMessage.left(rMessage.size() - 1); + return result; + } + + + + /************************************************************************** + * Implementation: Operators, Helper + **************************************************************************/ + + +#ifndef QT_NO_DATASTREAM + QDataStream &operator<<(QDataStream &rStream, + const LogError &rLogError) + { + QBuffer buffer; + buffer.open(QIODevice::WriteOnly); + QDataStream stream(&buffer); + + // version + quint16 version = 0; + stream << version; + // version 0 data + stream << rLogError.mCode + << rLogError.mContext + << rLogError.mMessage + << rLogError.mSymbol + << rLogError.mArgs + << rLogError.mCausingErrors; + + buffer.close(); + rStream << buffer.buffer(); + return rStream; + } + + + QDataStream &operator>>(QDataStream &rStream, + LogError &rLogError) + { + QByteArray array; + rStream >> array; + QBuffer buffer(&array); + buffer.open(QIODevice::ReadOnly); + QDataStream stream(&buffer); + + // version + quint16 version; + stream >> version; + // Version 0 data + QString level; + QString logger; + stream >> rLogError.mCode + >> rLogError.mContext + >> rLogError.mMessage + >> rLogError.mSymbol + >> rLogError.mArgs + >> rLogError.mCausingErrors; + + buffer.close(); + return rStream; + } +#endif // QT_NO_DATASTREAM + + +#ifndef QT_NO_DEBUG_STREAM + QDebug operator<<(QDebug debug, + const LogError &rLogError) + { + // Escape % sign + QString message = rLogError.message(); + message.replace(QLatin1String("%"), QLatin1String("%%")); + + debug.nospace() << "LogError(" + << "code:" << rLogError.code() << " " + << "context:" << rLogError.context() << " " + << "message:" << message << " " + << "symbol:" << rLogError.symbol() << " " + << "args:" << rLogError.args() + << "translatedMessage:" << rLogError.translatedMessage() + << ")"; + return debug.maybeSpace(); + } +#endif // QT_NO_DEBUG_STREAM + + +} // namespace Log4Qt diff --git a/src/log4qt/src/log4qt/helpers/logerror.h b/src/log4qt/src/log4qt/helpers/logerror.h new file mode 100644 index 0000000..06d1a67 --- /dev/null +++ b/src/log4qt/src/log4qt/helpers/logerror.h @@ -0,0 +1,550 @@ +/****************************************************************************** + * + * package: Log4Qt + * file: logerror.h + * created: September 2007 + * author: Martin Heinrich + * + * + * Copyright 2007 Martin Heinrich + * + * 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. + * + ******************************************************************************/ + +#ifndef LOG4QT_LOGERROR_H +#define LOG4QT_LOGERROR_H + + +/****************************************************************************** + * Dependencies + ******************************************************************************/ + +#include +#include + + +/****************************************************************************** + * Declarations + ******************************************************************************/ + +namespace Log4Qt +{ + /*! + * Creates an LogError object with the error message \a message, the error + * code \a code and the context \a context. The symbol of the error is + * set to \a code as string value. + * + * The following example logs an error, if a character is not a digit. + * + * \code + * if (!c.isDigit()) + * { + * Error e = LOG4QT_ERROR(QT_TR_NOOP("Found character '%1' where digit was expected."), + * LAYOUT_EXPECTED_DIGIT_ERROR, + * "Log4Qt::PatternFormatter"); + * e << QString(c); + * logger()->error(e); + * } + * \endcode + */ + #define LOG4QT_ERROR(message, code, context) \ + LogError(message, code, #code, context) + + /*! + * Creates an LogError object with the error message \a message and the + * error code \a code. The symbol of the error is set to \a code as string + * value. The context is set to the class name of the current object. The + * current objects class must be derived from QObject. + * + * The following example handles an error while opening a file. + * + * \code + * if (!mpFile->open(mode)) + * { + * LogError e = LOG4QT_QCLASS_ERROR(QT_TR_NOOP("Unable to open file '%1' for appender '%2'"), + * APPENDER_OPENING_FILE_ERROR); + * e << mFileName << name(); + * e.addCausingError(LogError(mpFile->errorString(), mpFile->error())); + * logger()->error(e); + * return; + * } + * \endcode + */ + #define LOG4QT_QCLASS_ERROR(message, code) \ + LogError(message, code, #code, this->metaObject()->className()) + + /*! + * \brief The class LogError represents an error. + * + * The class error allows storing error information in a structured way. + * The error message is stored separately from the information that may be + * substituted into the message string. This way it is possible to access + * all information after the error has been raised. It also allows to + * translate the error at a later point in time or to get a translated and + * a not translated error text (e.g. translated for the UI and not + * translated for a log). + * + * The message is accessed using message() and setMessage(). Arguments for + * the message can be added using addArg() or operator<<(). The arguments + * can be retrieved using args(). The message with substituted arguments + * is returned by messageWithArgs(). + * + * An error code can be set as integer value code() and/or a symbolic value + * symbol(). + * + * To allow the translation of the message the error stores the translation + * context (context(), setContext()). The translated message can be accessed + * using translatedMessage() or using translatedMessageWithArgs(), if it + * should contain the arguments. + * + * An error can have one or more related errors that caused it. An error is + * related using addCausingError(). All causing errors can be retrieved using + * causingErrors(). + * + * A per thread error can be maintained using lastError() and setLastError(). + * + * There are two macros avaiable to simplify the error creation. The macro + * \ref Log4Qt::LOG4QT_ERROR "LOG4QT_ERROR" is used with classes not derived + * from QObject. The macro \ref Log4Qt::LOG4QT_QCLASS_ERROR "LOG4QT_QCLASS_ERROR" + * is used with classes derived from QObject. + */ + class LogError + { + public: + + /*! + * The enum Encoding defines the 8-bit encoding of a character string + * arguments to \ref LogError::LogError(const char *, int, const char *, + * const char *, Encoding) "LogError::LogError()". + * + * \sa \ref LogError::LogError(const char *, int, const char *, const char *, Encoding) "LogError::LogError()" + */ + enum Encoding + { + /*! LATIN-1 */ + LATIN1, + /*! + * The encoding specified by QTextCodec::codecForTr() + * (Latin-1 if none has been set). + */ + CODECFORTR, + /*! UTF-8 */ + UNICODEUTF8 + }; + Q_ENUMS(Encoding) + + /*! + * Creates an empty error. The error code is set to 0 and all other + * members are set to be empty. + * + * \sa isEmpty() + */ + LogError(); + + /*! + * Creates an error with the Message \a rMessage and the error code + * \a code. The symbol for the error code is set to \a rSymbol and the + * context to \a rContext. + * + * \a rContext must be string that can be converted to Latin-1. The + * Latin-1 representation of the string is used with + * QApplication::translate(), if a translation for \a rMessage is + * requested. + * + * \sa translatedMessage(), translatedMessageWithArgs() + */ + LogError(const QString &rMessage, + int code = 0, + const QString &rSymbol = QString(), + const QString &rContext = QString()); + + /*! + * Creates an error with the Message \a pMessage and the error code + * \a code. The symbol for the error code is set to \a pSymbol and the + * context to \a pContext. + * + * \a encoding specifies the encoding of \a pMessage. \a pSymbol and + * \a pContext are expected to be Latin-1. + * + * \note To support the macros \ref Log4Qt::LOG4QT_ERROR "LOG4QT_ERROR" + * and \ref Log4Qt::LOG4QT_QCLASS_ERROR "LOG4QT_QCLASS_ERROR" + * the function tests, if \a pSymbol is the string representation of + * \a code. If it is, the symbol is set to be empty. Otherwise symbol + * is set to \a pSymbol. + * + * \sa translatedMessage(), translatedMessageWithArgs() + */ + LogError(const char *pMessage, + int code = 0, + const char *pSymbol = 0, + const char *pContext = 0, + Encoding encoding = LATIN1); + + // LogError(const LogError &rOther); // Use compiler default + // virtual ~LogError(); // Use compiler default + // LogError &operator=(const LogError &rOther); // Use compiler default + + /*! + * Returns the error code. + * + * \sa setCode() + */ + int code() const; + + /*! + * Returns the context for the error. + * + * \sa setContext() + */ + QString context() const; + + /*! + * Returns the error message. + * + * \sa setMessage() + */ + QString message() const; + + /*! + * Returns the symbol for the error code. + * + * \sa setSymbol() + */ + QString symbol() const; + + /*! + * Returns the translated error message. + * + * The translated message is created by calling + * QCoreApplication::translate() using context().toLatin1() as + * context and message.toUtf8() as message. + * + * \sa translatedMessageWithArgs() + */ + QString translatedMessage() const; + + /*! + * Sets the error code to \a code. + * + * \sa code() + */ + void setCode(int code); + + /*! + * Sets the context to \a rClassName. + * + * \a rContext must be string that can be converted to Latin-1. The + * Latin-1 representation of the string is used with + * QApplication::translate(), if a translation for \a rMessage is + * requestd. + * + * \sa context(), translatedMessage(), translatedMessageWithArgs() + */ + void setContext(const QString &rClassName); + + /*! + * Sets the error message to \a rMessage + * + * \sa message() + */ + void setMessage(const QString &rMessage); + + /*! + * Sets the symbol for the error code to \a rSymbol. + * + * \sa symbol() + */ + void setSymbol(const QString &rSymbol); + + /*! + * Returns the last error set for the current thread using + * setLastError(). + * + * \note: This function is thread-safe. + * + * \sa setLastError() + */ + static LogError lastError(); + + /*! + * Sets the last error for the current thread to \a rLogError. + * + * \note: This function is thread-safe. + * + * \sa lastError() + */ + static void setLastError(const LogError &rLogError); + + /*! + * Appends \a rArg to the list of arguments and returns a reference to + * this error. + * + * \sa operator<<(), args(), clearArgs() + */ + LogError &addArg(const QVariant &rArg); + + /*! + * This is an overloaded member function, provided for convenience. + */ + LogError &addArg(int arg); + + /*! + * This is an overloaded member function, provided for convenience. + */ + LogError &addArg(const QString &rArg); + + /*! + * Appends \a rLogError to the list of causing errors and returns a + * reference to this error. + * + * \sa causingErrors(), clearCausingErrors() + */ + LogError &addCausingError(const LogError &rLogError); + + /*! + * Returns the list of arguments that have been added to this error. + * + * \sa addArg(), operator<<(), clearArgs() + */ + QList args() const; + + /*! + * Returns the list of causing errors that have been added to this error. + * + * \sa addArg(), operator<<(), clearArgs() + */ + QList causingErrors() const; + + /*! + * Clears the list of arguments that have been added to this error. + * + * \sa addArg(), operator<<(), args() + */ + void clearArgs(); + + /*! + * Clears the list of causing errors that have been added to this error. + * + * \sa addCausingError(), causingErrors() + */ + void clearCausingErrors(); + + /*! + * Returns true, if the error code is 0 and the message is empty. + * Otherwise it returns false. + * + * \sa code(), message() + */ + bool isEmpty() const; + + /*! + * Returns the message with arguments. The arguments are incoorporated + * into the messag using QString::arg(). + * + * \sa QString::arg(), translatedMessageWithArgs() + */ + QString messageWithArgs() const; + + /*! + * Returns the translated message with arguments. The arguments are + * incoorporated into the messag using QString::arg(). + * + * \sa QString::arg(), messageWithArgs(), translatedMessage() + */ + QString translatedMessageWithArgs() const; + + /*! + * Appends \a rArg to the list of arguments and returns a reference to + * this error. + * + * \sa addArg() + */ + LogError &operator<<(const QVariant &rArg); + + /*! + * This is an overloaded member function, provided for convenience. + */ + LogError &operator<<(int arg); + + /*! + * This is an overloaded member function, provided for convenience. + */ + LogError &operator<<(const QString &rArg); + + /*! + * Returns a string representation of the error. + * + * The string has the following format: + * + * + * message (context::symbol, code): causing_error, causing_error + * + * + * If members are empty they are omitted: + * - Omit context, if empty + * - Omit symbol, if empty + * - Omit double colon with context and symbol, if both are empty + * - Omit code, if 0 + * - Omit bracket with context/symbol and code, if all are empty + * - Omit colon with causing errors, if no causing errors exist + */ + QString toString() const; + + private: + QString insertArgs(const QString &rMessage) const; + QString cleanMessage(const QString &rMessage); + + private: + int mCode; + QString mContext; + QString mMessage; + QString mSymbol; + QList mArgs; + QList mCausingErrors; + +#ifndef QT_NO_DATASTREAM + // Needs to be friend to stream objects + friend QDataStream &operator<<(QDataStream &rStream, + const LogError &rLogError); + friend QDataStream &operator>>(QDataStream &rStream, + LogError &rLogError); +#endif // QT_NO_DATASTREAM + }; + + + /************************************************************************** + * Operators, Helper + **************************************************************************/ + +#ifndef QT_NO_DATASTREAM + /*! + * \relates LogError + * + * Writes the given error \a rLogError to the given stream \a rStream, + * and returns a reference to the stream. + */ + QDataStream &operator<<(QDataStream &rStream, + const LogError &rLogError); + + /*! + * \relates LogError + * + * Reads an error from the given stream \a rStream into the given + * error \a rLogError, and returns a reference to the stream. + */ + QDataStream &operator>>(QDataStream &rStream, + LogError &rLogError); +#endif // QT_NO_DATASTREAM + +#ifndef QT_NO_DEBUG_STREAM + /*! + * \relates LogError + * + * Writes all object member variables to the given debug stream \a debug and + * returns the stream. + * + * + * %LogError(code:7 context:"Log4Qt::FileAppender" + * message:"Unable to open file '%1' for appender '%2'" + * symbol:"APPENDER_OPENING_FILE_ERROR" + * args:(QVariant(QString, "G:\logs\client.log") , QVariant(QString, "Client FileAppender") ) + * translatedMessage: "Unable to open file '%1' for appender '%2'" ) + * + * + * \sa QDebug + */ + QDebug operator<<(QDebug debug, + const LogError &rLogError); +#endif // QT_NO_DEBUG_STREAM + + + /************************************************************************** + * Inline + **************************************************************************/ + + inline int LogError::code() const + { return mCode; } + + inline QString LogError::context() const + { return mContext; } + + inline QString LogError::message() const + { return mMessage; } + + inline QString LogError::symbol() const + { return mSymbol; } + + inline void LogError::setCode(int code) + { mCode = code; } + + inline void LogError::setContext(const QString &rContext) + { mContext = rContext; } + + inline void LogError::setMessage(const QString &rMessage) + { mMessage = cleanMessage(rMessage); } + + inline void LogError::setSymbol(const QString &rSymbol) + { mSymbol = rSymbol; } + + inline LogError &LogError::addArg(const QVariant &rArg) + { mArgs << rArg; return *this; } + + inline LogError &LogError::addArg(int arg) + { mArgs << QVariant(arg); return *this; } + + inline LogError &LogError::addArg(const QString &rArg) + { mArgs << QVariant(rArg); return *this; } + + inline LogError &LogError::addCausingError(const LogError &rLogError) + { mCausingErrors << rLogError; return *this; } + + inline QList LogError::args() const + { return mArgs; } + + inline void LogError::clearArgs() + { mArgs.clear(); } + + inline void LogError::clearCausingErrors() + { mCausingErrors.clear(); } + + inline QList LogError::causingErrors() const + { return mCausingErrors; } + + inline bool LogError::isEmpty() const + { return mCode || !mMessage.isEmpty(); } + + inline QString LogError::messageWithArgs() const + { return insertArgs(message()); } + + inline QString LogError::translatedMessageWithArgs() const + { return insertArgs(translatedMessage()); } + + inline LogError &LogError::operator<<(const QVariant &rArg) + { return addArg(rArg); } + + inline LogError &LogError::operator<<(int arg) + { return addArg(arg); } + + inline LogError &LogError::operator<<(const QString &rArg) + { return addArg(rArg); } + + +} // namespace Log4Qt + + +Q_DECLARE_METATYPE(Log4Qt::LogError) +Q_DECLARE_TYPEINFO(Log4Qt::LogError, Q_MOVABLE_TYPE); + + +#endif // LOG4QT_ERROR_H diff --git a/src/log4qt/src/log4qt/helpers/logobject.cpp b/src/log4qt/src/log4qt/helpers/logobject.cpp new file mode 100644 index 0000000..44f1121 --- /dev/null +++ b/src/log4qt/src/log4qt/helpers/logobject.cpp @@ -0,0 +1,74 @@ +/****************************************************************************** + * + * package: Log4Qt + * file: logobject.cpp + * created: September 2007 + * author: Martin Heinrich + * + * + * Copyright 2007 Martin Heinrich + * + * 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. + * + ******************************************************************************/ + + +/****************************************************************************** + * Dependencies + ******************************************************************************/ + + +#include "log4qt/helpers/logobject.h" + +#include + + + +namespace Log4Qt +{ + + + /************************************************************************** + * Declarations + **************************************************************************/ + + + + /************************************************************************** + * C helper functions + **************************************************************************/ + + + + /************************************************************************** + * Class implementation: LogObject + **************************************************************************/ + + + + /************************************************************************** + * Implementation: Operators, Helper + **************************************************************************/ + + +#ifndef QT_NO_DEBUG_STREAM + QDebug operator<<(QDebug debug, + const LogObject &rLogObject) + { + return rLogObject.debug(debug); + } +#endif // QT_NO_DEBUG_STREAM + + + +} // namespace Log4Qt diff --git a/src/log4qt/src/log4qt/helpers/logobject.h b/src/log4qt/src/log4qt/helpers/logobject.h new file mode 100644 index 0000000..97b02c5 --- /dev/null +++ b/src/log4qt/src/log4qt/helpers/logobject.h @@ -0,0 +1,217 @@ +/****************************************************************************** + * + * package: Log4Qt + * file: logobject.h + * created: September 2007 + * author: Martin Heinrich + * + * + * changes: Sep 2008, Martin Heinrich: + * - Replaced usage of q_atomic_increment and q_atomic_decrement + * with QAtomicInt. + * Feb 2009, Martin Heinrich + * - Fixed a problem where the pParent parameter of the constructor + * was not passed on to the QObject constructor + * + * + * Copyright 2007 - 2009 Martin Heinrich + * + * 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. + * + ******************************************************************************/ + +#ifndef LOG4QT_LOGOBJECT_H +#define LOG4QT_LOGOBJECT_H + + +/****************************************************************************** + * Dependencies + ******************************************************************************/ + +#include + +#include "log4qt/helpers/classlogger.h" +#if QT_VERSION >= QT_VERSION_CHECK(4, 4, 0) +# include +# ifndef Q_ATOMIC_INT_REFERENCE_COUNTING_IS_ALWAYS_NATIVE +# warning "QAtomicInt reference counting is not native. The class Log4Qt::LogObject is not thread-safe." +# endif +#endif + + +namespace Log4Qt +{ + + class Logger; + + /*! + * \brief The class LogObject is the common base class for many classes + * in the package. + * + * The class inherits QObject to allow its subclass to be accessed using + * the Qt property system. + * + * LogObject objects provide a reference counter. A reference to the + * object is established by calling retain() and freed by calling + * release(). The object will delete itself when the reference counter + * is decremented to 0. + * + * A class specific logger can be accessed over logger(). + * + * The class also implements generic streaming to QDebug. Streaming an + * object to QDebug will invoke debug() to create class specific output. + * + * \note All the functions declared in this class are thread-safe. + * + * \sa \ref Ownership "Object ownership", + * LOG4QT_DECLARE_QCLASS_LOGGER + */ + class LogObject : public QObject + { + Q_OBJECT + + public: + /*! + * Creates a LogObject which is a child of \a pObject. + */ + LogObject(QObject *pObject = 0); + + /*! + * Destroys the LogObject. + */ + virtual ~LogObject(); + + private: + LogObject(const LogObject &rOther); // Not implemented + LogObject &operator=(const LogObject &rOther); // Not implemented + + public: + /*! + * Returns the value of the reference counter. + */ + int referenceCount() const; + + /*! + * Decrements the reference count of the object. If the reference count + * count reaches zero and the object does not have a parent the object + * is deleted. + */ + void release(); + + /*! + * Increments the reference count of the object. + */ + void retain(); + + protected: + #ifndef QT_NO_DEBUG_STREAM + /*! + * Writes all object member variables to the given debug stream + * \a rDebug and returns the stream. + * + * The member function is used by + * QDebug operator<<(QDebug debug, const LogObject &rLogObject) to + * generate class specific output. + * + * \sa QDebug operator<<(QDebug debug, const LogObject &rLogObject) + */ + virtual QDebug debug(QDebug &rDebug) const = 0; + + // Needs to be friend to access internal data + friend QDebug operator<<(QDebug debug, + const LogObject &rLogObject); + #endif // QT_NO_DEBUG_STREAM + + /*! + * Returns a pointer to a Logger named after of the object. + * + * \sa Logger::logger(const char *pName) + */ + Logger* logger() const; + + private: +#if QT_VERSION < QT_VERSION_CHECK(4, 4, 0) + volatile int mReferenceCount; +#else + mutable QAtomicInt mReferenceCount; +#endif + mutable ClassLogger mLog4QtClassLogger; + }; + + + /************************************************************************** + * Operators, Helper + **************************************************************************/ + + #ifndef QT_NO_DEBUG_STREAM + /*! + * \relates LogObject + * + * Writes all object member variables to the given debug stream \a debug + * and returns the stream. + * + * To handle sub-classing the function uses the virtual member function + * debug(). This allows each class to generate its own output. + * + * \sa QDebug, debug() + */ + QDebug operator<<(QDebug debug, + const LogObject &rLogObject); + #endif + + + /************************************************************************** + * Inline + **************************************************************************/ + + inline LogObject::LogObject(QObject *pParent) : + QObject(pParent), + mReferenceCount() + {} + + inline LogObject::~LogObject() + {} + + inline int LogObject::referenceCount() const +#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0) + { return mReferenceCount; } +#else + { return mReferenceCount.loadAcquire(); } +#endif + + inline void LogObject::release() +#if QT_VERSION < QT_VERSION_CHECK(4, 4, 0) + { if ((q_atomic_decrement(&mReferenceCount) == 0) && !parent()) + delete(this); } +#else + { if (!mReferenceCount.deref()) + delete(this); } +#endif + + inline void LogObject::retain() +#if QT_VERSION < QT_VERSION_CHECK(4, 4, 0) + { q_atomic_increment(&mReferenceCount); } +#else + { mReferenceCount.ref(); } +#endif + + inline Logger *LogObject::logger() const + { return mLog4QtClassLogger.logger(this); } + +} // namespace Log4Qt + + +// Q_DECLARE_TYPEINFO(Log4Qt::LogObject, Q_COMPLEX_TYPE); // Use default + + +#endif // LOG4QT_LOGOBJECT_H diff --git a/src/log4qt/src/log4qt/helpers/logobjectptr.cpp b/src/log4qt/src/log4qt/helpers/logobjectptr.cpp new file mode 100644 index 0000000..8084a79 --- /dev/null +++ b/src/log4qt/src/log4qt/helpers/logobjectptr.cpp @@ -0,0 +1,65 @@ +/****************************************************************************** + * + * package: Log4Qt + * file: logobjectptr.cpp + * created: September 2007 + * author: Martin Heinrich + * + * + * Copyright 2007 Martin Heinrich + * + * 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. + * + ******************************************************************************/ + + +/****************************************************************************** + * Dependencies + ******************************************************************************/ + + +#include "log4qt/helpers/logobjectptr.h" + +#include + + + +namespace Log4Qt +{ + + + /************************************************************************** + * Declarations + **************************************************************************/ + + + + /************************************************************************** + * C helper functions + **************************************************************************/ + + + + /************************************************************************** + * Class implementation: LogObjectPtr + **************************************************************************/ + + + + /************************************************************************** + * Implementation: Operators, Helper + **************************************************************************/ + + + +} // namespace Log4Qt diff --git a/src/log4qt/src/log4qt/helpers/logobjectptr.h b/src/log4qt/src/log4qt/helpers/logobjectptr.h new file mode 100644 index 0000000..6a8b613 --- /dev/null +++ b/src/log4qt/src/log4qt/helpers/logobjectptr.h @@ -0,0 +1,187 @@ +/****************************************************************************** + * + * package: Log4Qt + * file: logobjectptr.h + * created: September 2007 + * author: Martin Heinrich + * + * + * Copyright 2007 Martin Heinrich + * + * 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. + * + ******************************************************************************/ + +#ifndef LOG4QT_LOGOBJECTPTR_H +#define LOG4QT_LOGOBJECTPTR_H + + +/****************************************************************************** + * Dependencies + ******************************************************************************/ + +#include "log4qt/helpers/logobject.h" + +namespace Log4Qt +{ + /*! + * \brief The class LogObjectPtr implements automatic reference counting + * for LogObject objects. + */ + template + class LogObjectPtr + { + public: + /*! + * Constructs a 0 LogObject pointer. + */ + LogObjectPtr(); + + /*! + * Constructs a LogObject pointer that points to the same object then + * \a rOther. The reference counter of the object is incremented by + * one. + */ + LogObjectPtr(const LogObjectPtr &rOther); + + /*! + * Constructs a LogObject pointer that points to the object + * \a LogObject. The reference counter of the object is incremented by + * one. + */ + LogObjectPtr(T *pLogObject); + + /*! + * Assignment operator. Sets the LogObject pointer to point to the + * same object that \a rOther points to. The reference counter of the + * object the LogObjectPtr pointed to before the assignment is + * decremented by one. The reference counter of the object \a rOther + * is pointing to is incremented by one. + */ + LogObjectPtr &operator=(const LogObjectPtr &rOther); + + /*! + * Destructs the object. The reference counter of the object the + * LogObjectPtr points to is decremented by one. + */ + ~LogObjectPtr(); + + /*! + * Assignment operator. Sets the LogObject pointer to point to the + * object \a pLogObject. The reference counter of the object the + * LogObjectPtr pointed to before the assignment is decremented by + * one. The reference counter of the object \a pLogObject is pointing + * to is incremented by one. + */ + LogObjectPtr &operator=(T *pLogObject); + + /*! + * Arrow operator. Returns the LogObject the object points to. + */ + T *operator->() const; + + /*! + * Dereference operator. Returns a pointer to the LogObject the + * object points to. + */ + T &operator*() const; + + /*! + * Cast operator. Cast the object to the LogObject the object points + * to. + */ + operator T*() const; + + private: + void retain() const; + void release() const; + + private: + T *mpLogObject; + }; + + + /************************************************************************** + * Operators, Helper + **************************************************************************/ + + + /************************************************************************** + * Inline + **************************************************************************/ + + template + inline LogObjectPtr::LogObjectPtr() : + mpLogObject(0) + {} + + template + inline LogObjectPtr::LogObjectPtr(const LogObjectPtr &rOther) : + mpLogObject(rOther.mpLogObject) + { retain(); } + + template + inline LogObjectPtr::LogObjectPtr(T *pLogObject) : + mpLogObject(pLogObject) + { retain(); } + + template + inline LogObjectPtr &LogObjectPtr::operator=(const LogObjectPtr &rOther) + { rOther.retain(); + release(); + mpLogObject = rOther.mpLogObject; + return *this; } + + template + inline LogObjectPtr::~LogObjectPtr() + { release(); } + + template + inline LogObjectPtr &LogObjectPtr::operator=(T *pLogObject) + { if (pLogObject) + reinterpret_cast(pLogObject)->retain(); + release(); + mpLogObject = pLogObject; + return *this; } + + template + inline T *LogObjectPtr::operator->() const + { return mpLogObject; } + + template + inline T &LogObjectPtr::operator*() const + { return *mpLogObject; } + + template + inline LogObjectPtr::operator T*() const + { return mpLogObject; } + + template + inline void LogObjectPtr::retain() const + { if (mpLogObject) + reinterpret_cast(mpLogObject)->retain(); } + + template + inline void LogObjectPtr::release() const + { + if (mpLogObject) + reinterpret_cast(mpLogObject)->release(); + } + +} // namespace Log4Qt + + +//Q_DECLARE_TYPEINFO(Log4Qt::LogObjectPtr, Q_MOVABLE_TYPE); // Declare within T + + +#endif // LOG4QT_LOGOBJECTPTR_H diff --git a/src/log4qt/src/log4qt/helpers/optionconverter.cpp b/src/log4qt/src/log4qt/helpers/optionconverter.cpp new file mode 100644 index 0000000..15fb645 --- /dev/null +++ b/src/log4qt/src/log4qt/helpers/optionconverter.cpp @@ -0,0 +1,315 @@ +/****************************************************************************** + * + * package: Log4Qt + * file: optionconverter.cpp + * created: September 2007 + * author: Martin Heinrich + * + * + * changes Feb 2009, Martin Heinrich + * - Fixed a problem were OptionConverter::toBoolean would not + * return the default value, if the conversion fails. + * + * + * Copyright 2007 - 2009 Martin Heinrich + * + * 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. + * + ******************************************************************************/ + + +/****************************************************************************** + * Dependencies + ******************************************************************************/ + + +#include "log4qt/helpers/optionconverter.h" + +#include +#include "log4qt/helpers/logerror.h" +#include "log4qt/helpers/properties.h" +#include "log4qt/logger.h" +#include "log4qt/consoleappender.h" + + + +namespace Log4Qt +{ + + + /************************************************************************** + * Declarations + **************************************************************************/ + + + + /************************************************************************** + * C helper functions + **************************************************************************/ + + + LOG4QT_DECLARE_STATIC_LOGGER(logger, Log4Qt::OptionConverter) + + + + /************************************************************************** + * Class implementation: OptionConverter + **************************************************************************/ + + + QString OptionConverter::findAndSubst(const Properties &rProperties, + const QString &rKey) + { + QString value = rProperties.property(rKey); + if (value.isNull()) + return value; + + const QString begin_subst = QLatin1String("${"); + const QString end_subst = QLatin1String("}"); + const int begin_length = begin_subst.length(); + const int end_length = end_subst.length(); + + // Don't return a null string, the null string indicates that the + // property key does not exist. + QString result = QLatin1String(""); + + int i = 0; + int begin; + int end; + while (i < value.length()) + { + begin = value.indexOf(begin_subst, i); + if (begin == -1) + { + result += value.mid(i); + i = value.length(); + } + else + { + result += value.mid(i, begin - i); + end = value.indexOf(end_subst, i + begin_length); + if (end == -1) + { + LogError e = LOG4QT_ERROR(QT_TR_NOOP("Missing closing bracket for opening bracket at %1. Invalid subsitution in value %2."), + CONFIGURATOR_INVALID_SUBSTITUTION_ERROR, + "Log4Qt::OptionConverter"); + e << begin << value; + logger()->error(e); + return result; + } + else + { + result += findAndSubst(rProperties, value.mid(begin + begin_length, end - begin - end_length - 1)); + i = end + end_length; + } + } + } + return result; + } + + + QString OptionConverter::classNameJavaToCpp(const QString &rClassName) + { + const QLatin1String java_class_delimiter("."); + const QLatin1String cpp_class_delimiter("::"); + + QString result = rClassName; + return result.replace(java_class_delimiter, cpp_class_delimiter); + } + + + bool OptionConverter::toBoolean(const QString &rOption, + bool *p_ok) + { + const QLatin1String str_true("true"); + const QLatin1String str_enabled("enabled"); + const QLatin1String str_one("1"); + const QLatin1String str_false("false"); + const QLatin1String str_disabled("disabled"); + const QLatin1String str_zero("0"); + + if (p_ok) + *p_ok = true; + QString s = rOption.trimmed().toLower(); + if (s == str_true || s == str_enabled || s == str_one) + return true; + if (s == str_false || s == str_disabled || s == str_zero) + return false; + + if (p_ok) + *p_ok = false; + LogError e = LOG4QT_ERROR(QT_TR_NOOP("Invalid option string '%1' for a boolean"), + CONFIGURATOR_INVALID_OPTION_ERROR, + "Log4Qt::OptionConverter"); + e << rOption; + logger()->error(e); + return false; + } + + + bool OptionConverter::toBoolean(const QString &rOption, + bool default_value) + { + bool ok; + bool result = toBoolean(rOption, &ok); + if (ok) + return result; + else + return default_value; + } + + qint64 OptionConverter::toFileSize(const QString &rOption, + bool *p_ok) + { + // - Search for unit + // - Convert characters befor unit to int + // - Error, if + // - the conversion failed + // - the value < 0 + // - there is text after the unit characters + + if (p_ok) + *p_ok = false; + QString s = rOption.trimmed().toLower(); + qint64 f = 1; + int i; + i = s.indexOf(QLatin1String("kb")); + if (i >= 0) + f = 1024; + else + { + i = s.indexOf(QLatin1String("mb")); + if (i >= 0) + f = 1024 * 1024; + else + { + i = s.indexOf(QLatin1String("gb")); + if (i >= 0) + f = 1024 * 1024 * 1024; + } + } + if (i < 0) + i = s.length(); + bool ok; + qint64 value = s.left(i).toLongLong(&ok); + if (!ok || value < 0 || s.length() > i + 2) + { + LogError e = LOG4QT_ERROR(QT_TR_NOOP("Invalid option string '%1' for a file size"), + CONFIGURATOR_INVALID_OPTION_ERROR, + "Log4Qt::OptionConverter"); + e << rOption; + logger()->error(e); + return 0; + } + if (p_ok) + *p_ok = true; + return value * f; + } + + + int OptionConverter::toInt(const QString &rOption, + bool *p_ok) + { + int value = rOption.trimmed().toInt(p_ok); + if (*p_ok) + return value; + + LogError e = LOG4QT_ERROR(QT_TR_NOOP("Invalid option string '%1' for an integer"), + CONFIGURATOR_INVALID_OPTION_ERROR, + "Log4Qt::OptionConverter"); + e << rOption; + logger()->error(e); + return 0; + } + + qint64 OptionConverter::toQInt64(const QString &rOption, + bool *p_ok) + { + int value = rOption.trimmed().toLongLong(p_ok); + if (*p_ok) + return value; + + LogError e = LOG4QT_ERROR(QT_TR_NOOP("Invalid option string '%1' for an qint64"), + CONFIGURATOR_INVALID_OPTION_ERROR, + "Log4Qt::OptionConverter"); + e << rOption; + logger()->error(e); + return 0; + } + + Level OptionConverter::toLevel(const QString &rOption, + bool *p_ok) + { + bool ok; + Level level = Level::fromString(rOption.toUpper().trimmed(), &ok); + if (p_ok) + *p_ok = ok; + if (ok) + return level; + + LogError e = LOG4QT_ERROR(QT_TR_NOOP("Invalid option string '%1' for a level"), + CONFIGURATOR_INVALID_OPTION_ERROR, + "Log4Qt::OptionConverter"); + e << rOption; + logger()->error(e); + return level; + } + + + Level OptionConverter::toLevel(const QString &rOption, + const Level &rDefaultValue) + { + bool ok; + Level result = toLevel(rOption, &ok); + if (ok) + return result; + else + return rDefaultValue; + } + + + int OptionConverter::toTarget(const QString &rOption, + bool *p_ok) + { + const QLatin1String java_stdout("system.out"); + const QLatin1String cpp_stdout("stdout_target"); + const QLatin1String java_stderr("system.err"); + const QLatin1String cpp_stderr("stderr_target"); + + if (p_ok) + *p_ok = true; + QString s = rOption.trimmed().toLower(); + if (s == java_stdout || s == cpp_stdout) + return ConsoleAppender::STDOUT_TARGET; + if (s == java_stderr || s == cpp_stderr) + return ConsoleAppender::STDERR_TARGET; + + if (p_ok) + *p_ok = false; + LogError e = LOG4QT_ERROR(QT_TR_NOOP("Invalid option string '%1' for a target"), + CONFIGURATOR_INVALID_OPTION_ERROR, + "Log4Qt::OptionConverter"); + e << rOption; + logger()->error(e); + return ConsoleAppender::STDOUT_TARGET; + } + + + + /************************************************************************** + * Implementation: Operators, Helper + **************************************************************************/ + + + +} // namespace Log4Qt diff --git a/src/log4qt/src/log4qt/helpers/optionconverter.h b/src/log4qt/src/log4qt/helpers/optionconverter.h new file mode 100644 index 0000000..50027e4 --- /dev/null +++ b/src/log4qt/src/log4qt/helpers/optionconverter.h @@ -0,0 +1,150 @@ +/****************************************************************************** + * + * package: Log4Qt + * file: optionconverter.h + * created: September 2007 + * author: Martin Heinrich + * + * + * Copyright 2007 Martin Heinrich + * + * 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. + * + ******************************************************************************/ + +#ifndef LOG4QT_OPTIONCONVERTER_H +#define LOG4QT_OPTIONCONVERTER_H + + +/****************************************************************************** + * Dependencies + ******************************************************************************/ + +#include +#include "log4qt/level.h" + +namespace Log4Qt +{ + class Properties; + + /*! + * \brief The class OptionConverter provides functions to convert strings + * to property values. + */ + class OptionConverter + { + private: + OptionConverter(); + OptionConverter(const OptionConverter &rOther); // Not implemented + // virtual ~OptionConverter(); // Use compiler default + OptionConverter &operator=(const OptionConverter &rOther); // Not implemented + + public: + static QString findAndSubst(const Properties &rProperties, + const QString &rKey); + + /*! + * Returns the JAVA class name \a rClassName as C++ class name by + * replacing all . characters with ::. + */ + static QString classNameJavaToCpp(const QString &rClassName); + + /*! + * Converts the option \a rOption to a boolean value. Valid strings + * for true are "true", "enabled" and "1". Valid strings + * for false are "false", "disabled" and "0". If the conversion is + * successful, the target is returned and \a p_ok is set to true. + * Otherwise an error is written to the log, \a p_ok is set to false + * and false is returned. + */ + static bool toBoolean(const QString &rOption, + bool *p_ok = 0); + + static bool toBoolean(const QString &rOption, + bool default_value); + + /*! + * Converts the option string \a rOption to a file size. The string can + * be a positive integer followed by an optional unit suffix "KB", "MB" + * or "GB". If a unit suffix is specified the the integer is + * interpreted as kilobytes, megabytes or gigabytes. If the conversion + * is successful, the size is returned and \a p_ok is set to true. + * Otherwise an error is written to the log, \a p_ok is set to false + * and 0 is returned. + */ + static qint64 toFileSize(const QString &rOption, + bool *p_ok = 0); + + /*! + * Converts the option \a rOption to a integer value using + * QString::toInt(). If the conversion is successful, the integer is + * returned and \a p_ok is set to true. Otherwise an error is written + * to the log, \a p_ok is set to false and 0 is returned. + */ + static int toInt(const QString &rOption, + bool *p_ok = 0); + + /*! + * Converts the option \a rOption to a qint64 value using + * QString::toLongLong(). If the conversion is successful, the qint64 is + * returned and \a p_ok is set to true. Otherwise an error is written + * to the log, \a p_ok is set to false and 0 is returned. + */ + static qint64 toQInt64(const QString &rOption, + bool *p_ok = 0); + + /*! + * Converts the option \a rOption to a level value using + * Level::fromString(). If the conversion is successful, the level + * is returned and \a p_ok is set to true. Otherwise an error is + * written to the log, \a p_ok is set to false and a level with + * the value Level::NULL_INT is returned. + * + * \sa Level::fromString() + */ + static Level toLevel(const QString &rOption, + bool *p_ok = 0); + + static Level toLevel(const QString &rOption, + const Level &rDefaultValue); + + /*! + * Converts the option \a rOption to a ConsoleAppender::Target value. + * Valid strings for \a rOption are "System.out", "STDOUT_TARGET", + * "System.err" and "STDERR_TARGET". If the conversion is successful, + * the target is returned and \a p_ok is set to true. Otherwise an + * error is written to the log, \a p_ok is set to false and + * ConsoleAppender::STDOUT_TARGET is returned. + */ + static int toTarget(const QString &rOption, + bool *p_ok = 0); + }; + + + /************************************************************************** + * Operators, Helper + **************************************************************************/ + + + /************************************************************************** + * Inline + **************************************************************************/ + + +} // namespace Log4Qt + + +Q_DECLARE_TYPEINFO(Log4Qt::OptionConverter, Q_MOVABLE_TYPE); + + +#endif // LOG4QT_OPTIONCONVERTER_H diff --git a/src/log4qt/src/log4qt/helpers/patternformatter.cpp b/src/log4qt/src/log4qt/helpers/patternformatter.cpp new file mode 100644 index 0000000..60f5271 --- /dev/null +++ b/src/log4qt/src/log4qt/helpers/patternformatter.cpp @@ -0,0 +1,893 @@ +/****************************************************************************** + * + * package: Log4Qt + * file: patternformatter.cpp + * created: September 2007 + * author: Martin Heinrich + * + * + * changes Feb 2009, Martin Heinrich + * - Fixed VS 2008 unreferenced formal parameter warning by using + * Q_UNUSED in LiteralPatternConverter::convert. + * + * + * Copyright 2007 - 2009 Martin Heinrich + * + * 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. + * + ******************************************************************************/ + + + +/****************************************************************************** + * Dependencies + ******************************************************************************/ + +#include "log4qt/helpers/patternformatter.h" + +#include +#include +#include +#include "log4qt/helpers/datetime.h" +#include "log4qt/helpers/logerror.h" +#include "log4qt/layout.h" +#include "log4qt/logger.h" +#include "log4qt/loggingevent.h" + + + +namespace Log4Qt +{ + + + /************************************************************************** + *Declarations + **************************************************************************/ + + + /*! + * \brief The class FormattingInfo stores the formatting modifier for a + * pattern converter. + * + * \sa PatternConverter + */ + class FormattingInfo + { + public: + FormattingInfo() + { clear(); } + // FormattingInfo(const FormattingInfo &rOther); // Use compiler default + // virtual ~FormattingInfo(); // Use compiler default + // FormattingInfo &operator=(const FormattingInfo &rOther); // Use compiler default + + void clear(); + static QString intToString(int i); + + public: + int mMinLength; + int mMaxLength; + bool mLeftAligned; + }; + + + /*! + * \brief The class PatternConverter is the abstract base class for all + * pattern converters. + * + * PatternConverter handles the minimum and maximum modifier for a + * conversion character. The actual conversion is by calling the + * convert() member function of the derived class. + * + * \sa PatternLayout::format() + */ + class PatternConverter + { + public: + PatternConverter(const FormattingInfo &rFormattingInfo = FormattingInfo()) : + mFormattingInfo(rFormattingInfo) + {}; + virtual ~PatternConverter() + {}; + private: + PatternConverter(const PatternConverter &rOther); // Not implemented + PatternConverter &operator=(const PatternConverter &rOther); // Not implemented + + public: + void format(QString &rFormat, const LoggingEvent &rLoggingEvent) const; + + protected: + virtual QString convert(const LoggingEvent &rLoggingEvent) const = 0; + #ifndef QT_NO_DEBUG_STREAM + virtual QDebug debug(QDebug &rDebug) const = 0; + friend QDebug operator<<(QDebug, const PatternConverter &rPatternConverter); + #endif + + protected: + FormattingInfo mFormattingInfo; + }; + + + /*! + * \brief The class BasicPatternConverter converts several members of a + * LoggingEvent to a string. + * + * BasicPatternConverter is used by PatternLayout to convert members that + * do not reuquire additional formatting to a string as part of formatting + * the LoggingEvent. It handles the following conversion characters: + * 'm', 'p', 't', 'x' + * + * \sa PatternLayout::format() + * \sa PatternConverter::format() + */ + class BasicPatternConverter : public PatternConverter + { + public: + enum Type { + MESSAGE_CONVERTER, + NDC_CONVERTER, + LEVEL_CONVERTER, + THREAD_CONVERTER, + }; + + public: + BasicPatternConverter(const FormattingInfo &rFormattingInfo, + Type type) : + PatternConverter(rFormattingInfo), + mType(type) + {}; + // virtual ~BasicPatternConverter(); // Use compiler default + private: + BasicPatternConverter(const BasicPatternConverter &rOther); // Not implemented + BasicPatternConverter &operator=(const BasicPatternConverter &rOther); // Not implemented + + protected: + virtual QString convert(const LoggingEvent &rLoggingEvent) const; + #ifndef QT_NO_DEBUG_STREAM + virtual QDebug debug(QDebug &rDebug) const; + #endif + + private: + Type mType; + }; + + + /*! + * \brief The class DatePatternConverter converts the time stamp of a + * LoggingEvent to a string. + * + * DatePatternConverter is used by PatternLayout to convert the time stamp + * of a LoggingEvent to a string as part of formatting the LoggingEvent. + * It handles the 'd' and 'r' conversion character. + * + * \sa PatternLayout::format() + * \sa PatternConverter::format() + */ + class DatePatternConverter : public PatternConverter + { + public: + DatePatternConverter(const FormattingInfo &rFormattingInfo, + const QString &rFormat) : + PatternConverter(rFormattingInfo), + mFormat(rFormat) + {}; + // virtual ~DatePatternConverter(); // Use compiler default + private: + DatePatternConverter(const DatePatternConverter &rOther); // Not implemented + DatePatternConverter &operator=(const DatePatternConverter &rOther); // Not implemented + + protected: + virtual QString convert(const LoggingEvent &rLoggingEvent) const; + #ifndef QT_NO_DEBUG_STREAM + virtual QDebug debug(QDebug &rDebug) const; + #endif + + private: + QString mFormat; + }; + + + /*! + * \brief The class LiteralPatternConverter provides string literals. + * + * LiteralPatternConverter is used by PatternLayout to embed string + * literals as part of formatting the LoggingEvent. It handles string + * literals and the 'n' conversion character. + * + * \sa PatternLayout::format() + * \sa PatternConverter::format() + */ + class LiteralPatternConverter : public PatternConverter + { + public: + LiteralPatternConverter(const QString &rLiteral) : + PatternConverter(), + mLiteral(rLiteral) + {}; + // virtual ~LiteralPatternConverter(); // Use compiler default + private: + LiteralPatternConverter(const LiteralPatternConverter &rOther); // Not implemented + LiteralPatternConverter &operator=(const LiteralPatternConverter &rOther); // Not implemented + + protected: + virtual QString convert(const LoggingEvent &rLoggingEvent) const; + #ifndef QT_NO_DEBUG_STREAM + virtual QDebug debug(QDebug &rDebug) const; + #endif + + private: + QString mLiteral; + }; + + + /*! + * \brief The class LoggerPatternConverter converts the Logger name of a + * LoggingEvent to a string. + * + * LoggerPatternConverter is used by PatternLayout to convert the Logger + * name of a LoggingEvent to a string as part of formatting the + * LoggingEvent. It handles the 'c' conversion character. + * + * \sa PatternLayout::format() + * \sa PatternConverter::format() + */ + class LoggerPatternConverter : public PatternConverter + { + public: + LoggerPatternConverter(const FormattingInfo &rFormattingInfo, + int precision) : + PatternConverter(rFormattingInfo), + mPrecision(precision) + {}; + // virtual ~LoggerPatternConverter(); // Use compiler default + private: + LoggerPatternConverter(const LoggerPatternConverter &rOther); // Not implemented + LoggerPatternConverter &operator=(const LoggerPatternConverter &rOther); // Not implemented + + protected: + virtual QString convert(const LoggingEvent &rLoggingEvent) const; + #ifndef QT_NO_DEBUG_STREAM + virtual QDebug debug(QDebug &rDebug) const; + #endif + + private: + int mPrecision; + }; + + + + /*! + * \brief The class MDCPatternConverter converts the MDC data of a + * LoggingEvent to a string. + * + * MDCPatternConverter is used by PatternLayout to convert the MDC data of + * a LoggingEvent to a string as part of formatting the LoggingEvent. It + * handles the 'X' conversion character. + * + * \sa PatternLayout::format() + * \sa PatternConverter::format() + */ + class MDCPatternConverter : public PatternConverter + { + public: + MDCPatternConverter(const FormattingInfo &rFormattingInfo, + const QString &rKey) : + PatternConverter(rFormattingInfo), + mKey(rKey) + {}; + // virtual ~MDCPatternConverter(); // Use compiler default + private: + MDCPatternConverter(const MDCPatternConverter &rOther); // Not implemented + MDCPatternConverter &operator=(const MDCPatternConverter &rOther); // Not implemented + + protected: + virtual QString convert(const LoggingEvent &rLoggingEvent) const; + #ifndef QT_NO_DEBUG_STREAM + virtual QDebug debug(QDebug &rDebug) const; + #endif + + private: + QString mKey; + }; + + + #ifndef QT_NO_DEBUG_STREAM + QDebug operator<<(QDebug, const FormattingInfo &rFormattingInfo); + #endif + + + #ifndef QT_NO_DEBUG_STREAM + QDebug operator<<(QDebug, const PatternConverter &rPatternConverter); + #endif + + + + /************************************************************************** + * C helper functions + **************************************************************************/ + + + LOG4QT_DECLARE_STATIC_LOGGER(logger, Log4Qt::PatternFormatter) + + + + /************************************************************************** + * Class implementation: PatternFormatter + **************************************************************************/ + + + PatternFormatter::PatternFormatter(const QString &rPattern) : + mIgnoreCharacters(QLatin1String("CFlLM")), + mConversionCharacters(QLatin1String("cdmprtxX")), + mOptionCharacters(QLatin1String("cd")), + mPattern(rPattern), + mPatternConverters() + { + parse(); + } + + + PatternFormatter::~PatternFormatter() + { + PatternConverter *p_converter; + Q_FOREACH(p_converter, mPatternConverters) + delete p_converter; + } + + + QString PatternFormatter::format(const LoggingEvent &rLoggingEvent) const + { + QString result; + PatternConverter *p_converter; + Q_FOREACH(p_converter, mPatternConverters) + p_converter->format(result, rLoggingEvent); + return result; + } + + + bool PatternFormatter::addDigit(const QChar &rDigit, + int &rValue) + { + if (!rDigit.isDigit()) + return false; + + int digit_value = rDigit.digitValue(); + if (rValue > (INT_MAX - digit_value) / 10) + rValue = INT_MAX; + else + rValue = rValue * 10 + digit_value; + return true; + } + + + void PatternFormatter::createConverter(const QChar &rChar, + const FormattingInfo &rFormattingInfo, + const QString &rOption) + { + Q_ASSERT_X(mConversionCharacters.indexOf(rChar) >= 0, "PatternFormatter::createConverter", "Unknown conversion character" ); + + LogError e("Creating Converter for character '%1' min %2, max %3, left %4 and option '%5'"); + e << QString(rChar) + << FormattingInfo::intToString(rFormattingInfo.mMinLength) + << FormattingInfo::intToString(rFormattingInfo.mMaxLength) + << rFormattingInfo.mLeftAligned + << rOption; + logger()->trace(e); + + switch (rChar.toLatin1()) + { + case 'c': + mPatternConverters << new LoggerPatternConverter(rFormattingInfo, + parseIntegerOption(rOption)); + break; + case 'd': + { + QString option = rOption; + if (rOption.isEmpty()) + option = QLatin1String("ISO8601"); + mPatternConverters << new DatePatternConverter(rFormattingInfo, + option); + break; + } + case 'm': + mPatternConverters << new BasicPatternConverter(rFormattingInfo, + BasicPatternConverter::MESSAGE_CONVERTER); + break; + case 'p': + mPatternConverters << new BasicPatternConverter(rFormattingInfo, + BasicPatternConverter::LEVEL_CONVERTER); + break; + case 'r': + mPatternConverters << new DatePatternConverter(rFormattingInfo, + QLatin1String("TIME_RELATIVE")); + break; + case 't': + mPatternConverters << new BasicPatternConverter(rFormattingInfo, + BasicPatternConverter::THREAD_CONVERTER); + break; + case 'x': + mPatternConverters << new BasicPatternConverter(rFormattingInfo, + BasicPatternConverter::NDC_CONVERTER); + break; + case 'X': + mPatternConverters << new MDCPatternConverter(rFormattingInfo, + rOption); + break; + default: + Q_ASSERT_X(false, "PatternFormatter::createConverter", "Unknown pattern character"); + } + } + + + void PatternFormatter::createLiteralConverter(const QString &rLiteral) + { + logger()->trace("Creating literal LiteralConverter with Literal '%1'", + rLiteral); + mPatternConverters << new LiteralPatternConverter(rLiteral); + } + + + void PatternFormatter::parse() + { + enum State { + LITERAL_STATE, + ESCAPE_STATE, + MIN_STATE, + DOT_STATE, + MAX_STATE, + CHARACTER_STATE, + POSSIBLEOPTION_STATE, + OPTION_STATE + }; + + int i = 0; + QChar c; + char ch; + State state = LITERAL_STATE; + FormattingInfo formatting_info; + QString literal; + int converter_start; + int option_start; + while (i < mPattern.length()) + { + // i points to the current character + // c contains the current character + // ch contains the Latin1 equivalent of the current character + // i is incremented at the end of the loop to consume the character + // continue is used to change state without consuming the character + + c = mPattern.at(i); + ch = c.toLatin1(); + switch (state) + { + case LITERAL_STATE: + if (ch == '%') + { + formatting_info.clear(); + converter_start = i; + state = ESCAPE_STATE; + } else + literal += c; + break; + case ESCAPE_STATE: + if (ch == '%') + { + literal += c; + state = LITERAL_STATE; + } + else if (ch == 'n') + { + literal += Layout::endOfLine(); + state = LITERAL_STATE; + } + else + { + if (!literal.isEmpty()) + { + createLiteralConverter(literal); + literal.clear(); + } + if (ch == '-') + formatting_info.mLeftAligned = true; + else if (c.isDigit()) + { + formatting_info.mMinLength = c.digitValue(); + state = MIN_STATE; + } + else if (ch == '.') + state = DOT_STATE; + else + { + state = CHARACTER_STATE; + continue; + } + } + break; + case MIN_STATE: + if (!addDigit(c, formatting_info.mMinLength)) + { + if (ch == '.') + state = DOT_STATE; + else + { + state = CHARACTER_STATE; + continue; + } + } + break; + case DOT_STATE: + if (c.isDigit()) + { + formatting_info.mMaxLength = c.digitValue(); + state = MAX_STATE; + } + else + { + LogError e = LOG4QT_ERROR(QT_TR_NOOP("Found character '%1' where digit was expected."), + LAYOUT_EXPECTED_DIGIT_ERROR, + "Log4Qt::PatternFormatter"); + e << QString(c); + logger()->error(e); + } + break; + case MAX_STATE: + if (!addDigit(c, formatting_info.mMaxLength)) + { + state = CHARACTER_STATE; + continue; + } + break; + case CHARACTER_STATE: + if (mIgnoreCharacters.indexOf(c) >= 0) + state = LITERAL_STATE; + else if (mOptionCharacters.indexOf(c) >= 0) + state = POSSIBLEOPTION_STATE; + else if (mConversionCharacters.indexOf(c) >= 0) + { + createConverter(c, formatting_info); + state = LITERAL_STATE; + } + else + { + logger()->warn("Invalid conversion character '%1' at %2 in pattern '%3'", + c, i, mPattern); + createLiteralConverter(mPattern.mid(converter_start, i - converter_start + 1)); + state = LITERAL_STATE; + } + break; + case POSSIBLEOPTION_STATE: + if (ch == '{') + { + option_start = i; + state = OPTION_STATE; + } + else + { + createConverter(mPattern.at(i - 1), + formatting_info); + state = LITERAL_STATE; + continue; + } + break; + case OPTION_STATE: + if (ch == '}') + { + createConverter(mPattern.at(option_start - 1), + formatting_info, + mPattern.mid(option_start + 1, i - option_start - 1)); + state = LITERAL_STATE; + } + break; + default: + Q_ASSERT_X(false, "PatternFormatter::parse()", "Unknown parsing state constant"); + state = LITERAL_STATE; + } + i++; + } + + if (state != LITERAL_STATE) + { + logger()->warn("Unexptected end of pattern '%1'", mPattern); + if (state == ESCAPE_STATE) + literal += c; + else + literal += mPattern.mid(converter_start); + } + + if (!literal.isEmpty()) + createLiteralConverter(literal); + } + + + int PatternFormatter::parseIntegerOption(const QString &rOption) + { + if (rOption.isEmpty()) + return 0; + + bool ok; + int result = rOption.toInt(&ok); + if (!ok) + { + LogError e = LOG4QT_ERROR(QT_TR_NOOP("Option '%1' cannot be converted into an integer"), + LAYOUT_OPTION_IS_NOT_INTEGER_ERROR, + "Log4Qt::PatterFormatter"); + e << rOption; + logger()->error(e); + } + if (result < 0) + { + LogError e = LOG4QT_ERROR(QT_TR_NOOP("Option %1 isn't a positive integer"), + LAYOUT_INTEGER_IS_NOT_POSITIVE_ERROR, + "Log4Qt::PatterFormatter"); + e << result; + logger()->error(e); + result = 0; + } + return result; + } + + + /************************************************************************** + * Class implementation: FormattingInfo + **************************************************************************/ + + + void FormattingInfo::clear() + { + mMinLength = 0; + mMaxLength = INT_MAX; + mLeftAligned = false; + }; + + + QString FormattingInfo::intToString(int i) + { + if (i == INT_MAX) + return QLatin1String("INT_MAX"); + else + return QString::number(i); + } + + + + /************************************************************************** + * Class implementation: PatternConverter + **************************************************************************/ + + + void PatternConverter::format(QString &rFormat, const LoggingEvent &rLoggingEvent) const + { + const QLatin1Char space(' '); + QString s = convert(rLoggingEvent); + + if (s.length() > mFormattingInfo.mMaxLength) + rFormat += s.left(mFormattingInfo.mMaxLength); + else if (mFormattingInfo.mLeftAligned) + rFormat += s.leftJustified(mFormattingInfo.mMinLength, space, false); + else + rFormat += s.rightJustified(mFormattingInfo.mMinLength, space, false); + } + + + + /************************************************************************** + * Class implementation: BasicPatternConverter + **************************************************************************/ + + + QString BasicPatternConverter::convert(const LoggingEvent &rLoggingEvent) const + { + switch (mType) + { + case MESSAGE_CONVERTER: + return rLoggingEvent.message(); + break; + case NDC_CONVERTER: + return rLoggingEvent.ndc(); + break; + case LEVEL_CONVERTER: + return rLoggingEvent.level().toString(); + break; + case THREAD_CONVERTER: + return rLoggingEvent.threadName(); + break; + default: + Q_ASSERT_X(false, "BasicPatternConverter::convert()", "Unkown type constant"); + return QString(); + } + } + + + QDebug BasicPatternConverter::debug(QDebug &rDebug) const + { + QString type; + switch (mType) + { + case MESSAGE_CONVERTER: + type = QLatin1String("MESSAGE_CONVERTER"); + break; + case NDC_CONVERTER: + type = QLatin1String("NDC_CONVERTER"); + break; + case LEVEL_CONVERTER: + type = QLatin1String("LEVEL_CONVERTER"); + break; + case THREAD_CONVERTER: + type = QLatin1String("THREAD_CONVERTER"); + break; + default: + Q_ASSERT_X(false, "BasicPatternConverter::debug()", "Unkown type constant"); + } + rDebug.nospace() << "BasicPatternConverter(" + << mFormattingInfo + << "type:" << type + << ")"; + return rDebug.space(); + } + + + + /************************************************************************** + * Class implementation: DatePatternConverter + **************************************************************************/ + + + QString DatePatternConverter::convert(const LoggingEvent &rLoggingEvent) const + { + return DateTime::fromMilliSeconds(rLoggingEvent.timeStamp()).toString(mFormat); + } + + + QDebug DatePatternConverter::debug(QDebug &rDebug) const + { + rDebug.nospace() << "DatePatternConverter(" + << mFormattingInfo + << "format:" << mFormat + << ")"; + return rDebug.space(); + } + + + + /************************************************************************** + * Class implementation: LiteralPatternConverter + **************************************************************************/ + + + QString LiteralPatternConverter::convert(const LoggingEvent &rLoggingEvent) const + { + Q_UNUSED(rLoggingEvent); + return mLiteral; + }; + + + QDebug LiteralPatternConverter::debug(QDebug &rDebug) const + { + rDebug.nospace() << "LiteralPatternConverter(" + << mFormattingInfo + << "literal:" << mLiteral + << ")"; + return rDebug.space(); + } + + + + /************************************************************************** + * Class implementation: LoggerPatternConverter + **************************************************************************/ + + + QString LoggerPatternConverter::convert(const LoggingEvent &rLoggingEvent) const + { + if (!rLoggingEvent.logger()) + return QString(); + QString name = rLoggingEvent.logger()->name(); + if (mPrecision <= 0 || (name.isEmpty())) + return name; + + const QString separator(QLatin1String("::")); + + int i = mPrecision; + int begin = name.length(); + while ((i > 0) && (begin >= 0)) + { + begin = name.lastIndexOf(separator, begin - name.length() - 1); + i--; + } + if (begin < 0) + begin = 0; + else + begin += 2; + return name.mid(begin); + } + + + QDebug LoggerPatternConverter::debug(QDebug &rDebug) const + { + rDebug.nospace() << "LoggerPatternConverter(" + << mFormattingInfo + << "precision:" << mPrecision + << ")"; + return rDebug.space(); + } + + + + /****************************************************************************** + * Class implementation: MDCPatternConverter + ******************************************************************************/ + + + QString MDCPatternConverter::convert(const LoggingEvent &rLoggingEvent) const + { + return rLoggingEvent.mdc().value(mKey); + }; + + + QDebug MDCPatternConverter::debug(QDebug &rDebug) const + { + rDebug.nospace() << "MDCPatternConverter(" + << mFormattingInfo + << "key:" << mKey + << ")"; + return rDebug.space(); + } + + + + /************************************************************************** + * Implementation: Operators, Helper + **************************************************************************/ + + + #ifndef QT_NO_DEBUG_STREAM + QDebug operator<<(QDebug debug, const PatternFormatter &rPatternFormatter) + { + debug.nospace() << "PatternFormatter(" + << "pattern:" << rPatternFormatter.mPattern << " " + << "converters:("; + int i; + for (i = 0; i < rPatternFormatter.mPatternConverters.size(); i++) + { + if (i > 0) + debug.nospace() << ", "; + debug.nospace() << *rPatternFormatter.mPatternConverters.at(i); + } + debug.nospace() << ") )"; + return debug.space(); + } + #endif + + +#ifndef QT_NO_DEBUG_STREAM + QDebug operator<<(QDebug debug, const FormattingInfo &rFormattingInfo) + { + debug.nospace() << "FormattingInfo(" + << "min:" << FormattingInfo::intToString(rFormattingInfo.mMinLength) << " " + << "max:" << FormattingInfo::intToString(rFormattingInfo.mMaxLength) << " " + << "left:" << rFormattingInfo.mLeftAligned + << ")"; + return debug.space(); + } +#endif // QT_NO_DEBUG_STREAM + + +#ifndef QT_NO_DEBUG_STREAM + QDebug operator<<(QDebug debug, const PatternConverter &rPatternConverter) + { + return rPatternConverter.debug(debug); + } +#endif // QT_NO_DEBUG_STREAM + + + +} // namespace Log4Qt diff --git a/src/log4qt/src/log4qt/helpers/patternformatter.h b/src/log4qt/src/log4qt/helpers/patternformatter.h new file mode 100644 index 0000000..d5c2898 --- /dev/null +++ b/src/log4qt/src/log4qt/helpers/patternformatter.h @@ -0,0 +1,195 @@ +/****************************************************************************** + * + * package: Log4Qt + * file: patternformatter.h + * created: September 2007 + * author: Martin Heinrich + * + * + * Copyright 2007 Martin Heinrich + * + * 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. + * + ******************************************************************************/ + +#ifndef LOG4QT_PATTERNFORMATTER_H +#define LOG4QT_PATTERNFORMATTER_H + + +/****************************************************************************** + * Dependencies + ******************************************************************************/ + +#include +#include + + +/****************************************************************************** + * Declarations + ******************************************************************************/ + + +namespace Log4Qt +{ + + class FormattingInfo; + class PatternConverter; + class LoggingEvent; + + /*! + * \brief The class PatternFormatter formats a logging event based on a + * pattern string. + * + * The class PatternFormatter formats a LoggingEvent base on a pattern + * string. It is used by the patternLayout and TTCCLayout class to + * implement the formatting. + * + * On object construction the provided patterns tring is parsed. Based on + * the information found a chain of PatternConverter is created. Each + * PatternConverter handles a certain member of a LoggingEvent. + * + * \sa PatternLayout::format() + * \sa TTCCLayout::format() + */ + class PatternFormatter + { + public: + /*! + * Creates a PatternFormatter using a the specified \a rPattern. + */ + PatternFormatter(const QString &rPattern); + + /*! + * Destroys the PatternFormatter and all PatternConverter. + */ + virtual ~PatternFormatter(); + + private: + PatternFormatter(const PatternFormatter &rOther); // Not implemented + PatternFormatter &operator=(const PatternFormatter &rOther); // Not implemented + + public: + /*! + * Formats the given \a rLoggingEvent using the chain of + * PatternConverter created during construction from the specified + * pattern. + */ + QString format(const LoggingEvent &rLoggingEvent) const; + + private: + /*! + * If the character \a rDigit is a digit the digit is added to the + * integer \a rValue and the function returns true. Otherwise the + * function returns false. + * + * The function adds the digit by multiplying the existing value + * with ten and adding the numerical value of the digit. If the + * maximum integer value would be exceeded by the operation + * \a rValue is set to INT_MAX. + */ + bool addDigit(const QChar &rDigit, + int &rValue); + + /*! + * Creates a PatternConverter based on the specified conversion + * character \a rChar, the formatting information + * \a rFormattingInfo and the option \a rOption. + * + * The PatternConverter converter is appended to the list of + * PatternConverters. + */ + void createConverter(const QChar &rChar, + const FormattingInfo &rFormattingInfo, + const QString &rOption = QString()); + + /*! + * Creates a LiteralPatternConverter with the string literal + * \a rLiteral. + * + * The PatternConverter converter is appended to the list of + * PatternConverters. + */ + void createLiteralConverter(const QString &rLiteral); + + /*! + * Parses the pattern string specified on construction and creates + * PatternConverter according to it. + */ + void parse(); + + /*! + * Parses an integer option from an option string. If the string is + * not a valid integer or the integer value is less then zero, zero + * is returned. Returns the end of line seperator for the operating + * system. + */ + int parseIntegerOption(const QString &rOption); + + private: + const QString mIgnoreCharacters; + const QString mConversionCharacters; + const QString mOptionCharacters; + QString mPattern; + QList mPatternConverters; + + // Needs to be friend to access internal data + friend QDebug operator<<(QDebug, const PatternFormatter &rPatternFormatter); + }; + + + /************************************************************************** + * Operators, Helper + **************************************************************************/ + +#ifndef QT_NO_DEBUG_STREAM + /*! + * \relates PatternFormatter + * + * Writes all object member variables to the given debug stream \a rDebug and + * returns the stream. + * + * + * %PatternFormatter(pattern:"%r [%t] %p %c %x - %m%n" + * converters:( + * DatePatternConverter(FormattingInfo(min:"0" max:"INT_MAX" left:false) format: "TIME_RELATIVE" ) , + * LiteralPatternConverter(FormattingInfo(min:"0" max:"INT_MAX" left:false) literal: " [" ) , + * BasicPatternConverter(FormattingInfo(min:"0" max:"INT_MAX" left:false) type: "THREAD_CONVERTER" ) , + * LiteralPatternConverter(FormattingInfo(min:"0" max:"INT_MAX" left:false) literal: "] " ) , + * BasicPatternConverter(FormattingInfo(min:"0" max:"INT_MAX" left:false) type: "LEVEL_CONVERTER" ) , + * LiteralPatternConverter(FormattingInfo(min:"0" max:"INT_MAX" left:false) literal: " " ) , + * LoggerPatternConverter(FormattingInfo(min:"0" max:"INT_MAX" left:false) precision: 0 ) , + * LiteralPatternConverter(FormattingInfo(min:"0" max:"INT_MAX" left:false) literal: " " ) , + * BasicPatternConverter(FormattingInfo(min:"0" max:"INT_MAX" left:false) type: "NDC_CONVERTER" ) , + * LiteralPatternConverter(FormattingInfo(min:"0" max:"INT_MAX" left:false) literal: " - " ) , + * BasicPatternConverter(FormattingInfo(min:"0" max:"INT_MAX" left:false) type: "MESSAGE_CONVERTER" ) , + * LiteralPatternConverter(FormattingInfo(min:"0" max:"INT_MAX" left:false) literal: "" ) ) ) + * + * \sa QDebug + */ + QDebug operator<<(QDebug debug, + const PatternFormatter &rPatternFormatter); +#endif // QT_NO_DEBUG_STREAM + + + /************************************************************************** + * Inline + **************************************************************************/ + + +} // namespace Log4Qt + + +Q_DECLARE_TYPEINFO(Log4Qt::PatternFormatter, Q_MOVABLE_TYPE); + + +#endif // LOG4QT_PATTERNFORMATTER_H diff --git a/src/log4qt/src/log4qt/helpers/properties.cpp b/src/log4qt/src/log4qt/helpers/properties.cpp new file mode 100644 index 0000000..96d04d7 --- /dev/null +++ b/src/log4qt/src/log4qt/helpers/properties.cpp @@ -0,0 +1,364 @@ +/****************************************************************************** + * + * package: Log4Qt + * file: properties.cpp + * created: September 2007 + * author: Martin Heinrich + * + * + * Copyright 2007 Martin Heinrich + * + * 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. + * + ******************************************************************************/ + + + +/****************************************************************************** + * Dependencies + ******************************************************************************/ + + +#include "log4qt/helpers/properties.h" + +#include +#include +#include +#include +#include "log4qt/logger.h" + + + +namespace Log4Qt +{ + + + + /************************************************************************** + *Declarations + **************************************************************************/ + + + + /************************************************************************** + * C helper functions + **************************************************************************/ + + + LOG4QT_DECLARE_STATIC_LOGGER(logger, Log4Qt::Properties) + + + + /************************************************************************** + * Class implementation: Properties + **************************************************************************/ + + + void Properties::load(QIODevice *pDevice) + { + const QLatin1Char append_char(msEscapeChar); + + if (!pDevice) + { + logger()->warn("No device specified for load."); + return; + } + + QTextStream stream(pDevice); + QString line; + int line_number = 0; + QString property; + int property_start_line = 1; + + do { + line = trimLeft(stream.readLine()); + line_number++; + + if (!line.isEmpty() && line.at(line.length() - 1) == append_char) + property += line.left(line.length() - 1); + else + { + property += line; + parseProperty(property, property_start_line); + property.clear(); + property_start_line = line_number + 1; + } + } + while (!line.isNull()); + } + + + void Properties::load(const QSettings &rSettings) + { + QStringList keys = rSettings.childKeys(); + QString key; + Q_FOREACH(key, keys) + insert(key, rSettings.value(key).toString()); + } + + + QString Properties::property(const QString &rKey) const + { + // Null string indicates the property does not contain the key. + + if (contains(rKey)) + { + QString value = this->value(rKey); + if (value.isNull()) + return QString(QLatin1String("")); + else + return value; + } + + if (mpDefaultProperties) + return mpDefaultProperties->property(rKey); + else + return QString(); + } + + + QString Properties::property(const QString &rKey, + const QString &rDefaultValue) const + { + QString value = property(rKey); + if (value.isNull()) + return rDefaultValue; + else + return value; + } + + + QStringList Properties::propertyNames() const + { + QStringList default_keys; + if (mpDefaultProperties) + default_keys = mpDefaultProperties->propertyNames(); + + QStringList keys = this->keys(); + QString key; + Q_FOREACH(key, default_keys) + if (!keys.contains(key)) + keys << key; + + return keys; + } + + + void Properties::parseProperty(const QString &rProperty, + int line) + { + Q_ASSERT_X(rProperty == trimLeft(rProperty), "parseProperty()", "rProperty has leading spaces"); + + enum State + { + KEY_STATE, + KEYSPACE_STATE, + SPACEVALUE_STATE, + VALUE_STATE, + KEYESCAPE_STATE, + VALUEESCAPE_STATE, + UNICODEESCAPE_STATE + }; + const QString value_escape_codes =QLatin1String(msValueEscapeCodes); + const QString value_escape_chars = QLatin1String(msValueEscapeChars); + Q_ASSERT_X(value_escape_codes.length() == value_escape_chars.length(), "parseProperty()", "Value escape sequence character definition does not map"); + const QString key_escape_codes = QLatin1String(msKeyEscapeCodes); + const QString key_escape_chars = QLatin1String(msKeyEscapeChars); + Q_ASSERT_X(key_escape_codes.length() == key_escape_chars.length(), "parseProperty()", "Key escape sequence character definition does not map"); + + if (rProperty.isEmpty()) + return; + + int i = 0; + QChar c; + char ch; + State state = KEY_STATE; + QString key; + QString value; + QString *p_string = &key; + uint ucs; + int ucs_digits; + while (i < rProperty.length()) + { + // i points to the current character. + // c contains the current character + // ch contains the Latin1 equivalent of the current character + // i is incremented at the end of the loop to consume the character. + // continue is used to change state without consuming the character + + c = rProperty.at(i); + ch = c.toLatin1(); + + switch (state) + { + case KEY_STATE: + if (ch == '!' || ch == '#' ) + return; + else if (c.isSpace()) + { + p_string = &value; + state = KEYSPACE_STATE; + } + else if (ch == '=' || ch == ':') + { + p_string = &value; + state = SPACEVALUE_STATE; + } + else if (ch == msEscapeChar) + state = KEYESCAPE_STATE; + else + *p_string += c; + break; + case KEYSPACE_STATE: + if (ch == '=' || ch == ':') + state = SPACEVALUE_STATE; + else if (!c.isSpace()) + { + *p_string += c; + state = VALUE_STATE; + } + break; + case SPACEVALUE_STATE: + if (!c.isSpace()) + { + *p_string += c; + state = VALUE_STATE; + } + break; + case VALUE_STATE: + if (ch == msEscapeChar) + state = VALUEESCAPE_STATE; + else + *p_string += c; + break; + case KEYESCAPE_STATE: + { + int convert = key_escape_codes.indexOf(c); + if (convert >= 0) + *p_string += key_escape_chars.at(convert); + else + { + logger()->warn("Unknown escape sequence '\\%1' in key of property starting at line %2", + QString(c), + line); + *p_string += c; + } + state = KEY_STATE; + break; + } + case VALUEESCAPE_STATE: + { + int convert = value_escape_codes.indexOf(c); + if (convert >= 0) + { + *p_string += value_escape_chars.at(convert); + state = VALUE_STATE; + } + else if (ch == 'u') + { + ucs = 0; + ucs_digits = 0; + state = UNICODEESCAPE_STATE; + } + else + { + logger()->warn("Unknown escape sequence '\\%1' in value of property starting at line %2", QString(c), line); + *p_string += c; + state = VALUE_STATE; + } + break; + } + case UNICODEESCAPE_STATE: + { + int hex = hexDigitValue(c); + if (hex >= 0) + { + ucs = ucs * 16 + hex; + ucs_digits++; + if (ucs_digits == 4 || i == rProperty.length() - 1) + { + *p_string += QChar(ucs); + state = VALUE_STATE; + } + } + else + { + if (ucs_digits > 0) + *p_string += QChar(ucs); + state = VALUE_STATE; + continue; + } + break; + } + default: + Q_ASSERT_X(false, "Properties::parseProperty()", "Unknown state constant"); + return; + } + i++; + } + + if (key.isEmpty() && !value.isEmpty()) + logger()->warn("Found value with no key in property starting at line %1", line); + + logger()->trace("Loaded property '%1' : '%2'", key, value); + insert(key, value); + } + + + int Properties::hexDigitValue(const QChar &rDigit) + { + bool ok; + int result = QString(rDigit).toInt(&ok, 16); + if (!ok) + return -1; + else + return result; + } + + + QString Properties::trimLeft(const QString &rLine) + { + int i = 0; + while (i < rLine.length() && rLine.at(i).isSpace()) + i++; + return rLine.right(rLine.length() - i); + } + + + const char Properties::msEscapeChar ='\\'; + const char *Properties::msValueEscapeCodes = "tnr\\\"\' "; + const char *Properties::msValueEscapeChars = "\t\n\r\\\"\' "; + const char *Properties::msKeyEscapeCodes = " :="; + const char *Properties::msKeyEscapeChars = " :="; + + + + /************************************************************************** + * Implementation: Operators, Helper + **************************************************************************/ + + +#ifndef QT_NO_DEBUG_STREAM + QDebug operator<<(QDebug debug, const Properties &rProperties) + { + debug.nospace() << "Properties(" + << "default:" << rProperties.defaultProperties() << " " + << "properties:" << *reinterpret_cast *>(&rProperties) + << ")"; + return debug.space(); + } +#endif + + + +} // namespace Log4Qt diff --git a/src/log4qt/src/log4qt/helpers/properties.h b/src/log4qt/src/log4qt/helpers/properties.h new file mode 100644 index 0000000..a9601f4 --- /dev/null +++ b/src/log4qt/src/log4qt/helpers/properties.h @@ -0,0 +1,161 @@ +/****************************************************************************** + * + * package: Log4Qt + * file: properties.h + * created: September + * author: Martin Heinrich + * + * + * Copyright 2007 Martin Heinrich + * + * 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. + * + ******************************************************************************/ + +#ifndef LOG4QT_PROPERTIES_H +#define LOG4QT_PROPERTIES_H + + +/****************************************************************************** + * Dependencies + ******************************************************************************/ + +#include +#include + + +/****************************************************************************** + * Declarations + ******************************************************************************/ + +class QIODevice; +class QSettings; + + +namespace Log4Qt +{ + /*! + * \brief The class Properties implements a JAVA property hash. + */ + class Properties : public QHash + { + public: + Properties(Properties *pDefaultProperties = 0); + // virtual ~Properties(); // Use compiler default + // Properties(const Properties &rOther); // Use compiler default + // Properties &operator=(const Properties &rOther); // Not implemented + + public: + Properties *defaultProperties() const; + QString property(const QString &rKey) const; + QString property(const QString &rKey, + const QString &rDefaultValue) const; + void setDefaultProperties(Properties *pDefault); + void setProperty(const QString &rKey, + const QString &rValue); + + // JAVA: void list(QTextStream &rTextStream); + void load(QIODevice *pDevice); + + /*! + * Reads all child keys from the QSettings object \a rSettings and + * inserts them into this object. The value is created using + * QVariant::toString(). Types that do not support toString() are + * resulting in an empty string. + * + * \code + * QSettings settings; + * settings.setValue("Package", "Full"); + * settings.setValue("Background", Qt::white); + * settings.setValue("Support", true); + * settings.setValue("Help/Language", "en_UK"); + * + * Properties properties + * properties.load(&settings) + * + * // properties (("Package", "Full"), ("Background", ""), ("Support", "true")) + * \endcode + */ + void load(const QSettings &rSettings); + + QStringList propertyNames() const; + // JAVA: void save(QIODevice *pDevice) const; + + private: + void parseProperty(const QString &rProperty, + int line); + static int hexDigitValue(const QChar &rDigit); + static QString trimLeft(const QString &rString); + + private: + Properties *mpDefaultProperties; + static const char msEscapeChar; + static const char *msValueEscapeCodes; + static const char *msValueEscapeChars; + static const char *msKeyEscapeCodes; + static const char *msKeyEscapeChars; + }; + + + /************************************************************************** + * Operators, Helper + **************************************************************************/ + +#ifndef QT_NO_DEBUG_STREAM + /*! + * \relates Properties + * + * Writes all object member variables to the given debug stream \a rDebug and + * returns the stream. + * + * + * %Properties(default:0x0 properties:QHash(("log4j.appender.testAppender.layout", "org.apache.log4j.PatternLayout ") + * ("log4j.appender.testAppender.layout.ConversionPattern", "[%t] %-5p %l: %m%n") + * ("log4j.appender.testAppender.Append", "false ") + * ("log4j.appender.testAppender.File", "output/temp ") + * ("log4j.rootCategory", "TRACE, testAppender") + * ("log4j.appender.testAppender", "org.apache.log4j.FileAppender")) ) + * + * \sa QDebug + */ + QDebug operator<<(QDebug debug, + const Properties &rProperties); +#endif // QT_NO_DEBUG_STREAM + + + /************************************************************************** + * Inline + **************************************************************************/ + + inline Properties::Properties(Properties *pDefaultProperties) : + mpDefaultProperties(pDefaultProperties) + {} + + inline Properties *Properties::defaultProperties() const + { return mpDefaultProperties; } + + inline void Properties::setDefaultProperties(Properties *pDefaultProperties) + { mpDefaultProperties = pDefaultProperties; } + + inline void Properties::setProperty(const QString &rKey, + const QString &rValue) + { insert(rKey, rValue); } + + +} // namespace Log4Qt + + +Q_DECLARE_TYPEINFO(Log4Qt::Properties, Q_MOVABLE_TYPE); + + +#endif // LOG4QT_PROPERTIES_H diff --git a/src/log4qt/src/log4qt/hierarchy.cpp b/src/log4qt/src/log4qt/hierarchy.cpp new file mode 100644 index 0000000..283c7fd --- /dev/null +++ b/src/log4qt/src/log4qt/hierarchy.cpp @@ -0,0 +1,212 @@ +/****************************************************************************** + * + * package: Log4Qt + * file: hierarchy.cpp + * created: September 2007 + * author: Martin Heinrich + * + * + * changes: Sep 2008, Martin Heinrich: + * - Fixed problem in Qt 4.4 where QReadWriteLock is by default + * non-recursive. + * + * + * Copyright 2007 - 2008 Martin Heinrich + * + * 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. + * + ******************************************************************************/ + + + +/****************************************************************************** + * Dependencies + ******************************************************************************/ + + +#include "log4qt/hierarchy.h" + +#include +#include "log4qt/logger.h" + + + +namespace Log4Qt +{ + + + /************************************************************************** + * Declarations + **************************************************************************/ + + + + /************************************************************************** + * C helper functions + **************************************************************************/ + + + LOG4QT_DECLARE_STATIC_LOGGER(static_logger, Log4Qt::LoggerRepository) + + + + /************************************************************************** + * Class implementation: Hierarchy + **************************************************************************/ + + + Hierarchy::Hierarchy() : +#if QT_VERSION < QT_VERSION_CHECK(4, 4, 0) + mObjectGuard(), +#else + mObjectGuard(QReadWriteLock::Recursive), +#endif + mLoggers(), + mThreshold(Level::NULL_INT), + mpRootLogger(logger(QString())) + { + // Store root logger to allow rootLogger() to be const + } + + + Hierarchy::~Hierarchy() + { + static_logger()->warn("Unexpected destruction of Hierarchy"); + + // QWriteLocker locker(&mObjectGuard); + // + // resetConfiguration(); + // clear(); + // delete mpRootLogger; + } + + + bool Hierarchy::exists(const QString &rName) const + { + QReadLocker locker(&mObjectGuard); + + return mLoggers.contains(rName); + } + + + Logger *Hierarchy::logger(const QString &rName) + { + QWriteLocker locker(&mObjectGuard); + + return createLogger(rName); + } + + + QList Hierarchy::loggers() const + { + QReadLocker locker(&mObjectGuard); + + return mLoggers.values(); + } + + + void Hierarchy::setThreshold(const QString &rThreshold) + { + setThreshold(Level::fromString(rThreshold)); + } + + + void Hierarchy::resetConfiguration() + { + QWriteLocker locker(&mObjectGuard); + + // Reset all loggers. + // Leave log, qt and root logger to the last to allow debugging of shutdown. + + Logger *p_logging_logger = logger(QLatin1String("Log4Qt")); + Logger *p_qt_logger = logger(QLatin1String("Qt")); + Logger *p_root_logger = rootLogger(); + + Logger *p_logger; + Q_FOREACH(p_logger, mLoggers) + { + if ((p_logger == p_logging_logger) || (p_logger == p_qt_logger) || (p_logger == p_root_logger)) + continue; + resetLogger(p_logger, Level::NULL_INT); + } + resetLogger(p_qt_logger, Level::NULL_INT); + resetLogger(p_logging_logger, Level::NULL_INT); + resetLogger(p_root_logger, Level::DEBUG_INT); + } + + + void Hierarchy::shutdown() + { + static_logger()->debug("Shutting down Hierarchy"); + resetConfiguration(); + } + + +#ifndef QT_NO_DEBUG_STREAM + QDebug Hierarchy::debug(QDebug &rDebug) const + { + rDebug.nospace() << "Hierarchy(" + << "loggers:" << loggers().count() << " " + << "threshold:" << threshold().toString() << " " + << "root-level:" << rootLogger()->level().toString() << " " + << "root-appenders:" << rootLogger()->appenders().count() + << ")"; + return rDebug.space(); + } +#endif // QT_NO_DEBUG_STREAM + + + Logger *Hierarchy::createLogger(const QString &rName) + { + // Q_ASSERT_X(, "Hierarchy::createLogger", "Lock must be held by caller") + + const QString name_separator = QLatin1String("::"); + + Logger *p_logger = mLoggers.value(rName, 0); + if (p_logger != 0) + return p_logger; + + if (rName.isEmpty()) + { + p_logger = new Logger(this, Level::DEBUG_INT, QLatin1String("root"), 0); + mLoggers.insert(QString(), p_logger); + return p_logger; + } + QString parent_name; + int index = rName.lastIndexOf(name_separator); + if (index >=0) + parent_name = rName.left(index); + p_logger = new Logger(this, Level::NULL_INT, rName, createLogger(parent_name)); + mLoggers.insert(rName, p_logger); + return p_logger; + } + + + void Hierarchy::resetLogger(Logger *pLogger, Level level) const + { + // Q_ASSERT_X(, "Hierarchy::resetLogger", "Lock must be held by caller") + + pLogger->removeAllAppenders(); + pLogger->setAdditivity(true); + pLogger->setLevel(level); + } + + + + /************************************************************************** + * Implementation: Operators, Helper + **************************************************************************/ + + + +} // namespace Log4Qt diff --git a/src/log4qt/src/log4qt/hierarchy.h b/src/log4qt/src/log4qt/hierarchy.h new file mode 100644 index 0000000..18a90eb --- /dev/null +++ b/src/log4qt/src/log4qt/hierarchy.h @@ -0,0 +1,141 @@ +/****************************************************************************** + * + * package: Log4Qt + * file: hierarchy.h + * created: September 2007 + * author: Martin Heinrich + * + * + * Copyright 2007 Martin Heinrich + * + * 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. + * + ******************************************************************************/ + +#ifndef LOG4QT_HIERARCHY_H +#define LOG4QT_HIERARCHY_H + + +/****************************************************************************** + * Dependencies + ******************************************************************************/ + +#include "log4qt/loggerrepository.h" + +#include +#include + + +/****************************************************************************** + * Declarations + ******************************************************************************/ + +namespace Log4Qt +{ + + /*! + * \brief The class Hierarchy implements a logger repository. + * + * \note All the functions declared in this class are thread-safe. + */ + class Hierarchy : public LoggerRepository + { + public: + Hierarchy(); + // Hierarchy(const Hierarchy &rOther); // Use compiler default + virtual ~Hierarchy(); + // Hierarchy &operator=(const Hierarchy &rOther); // Use compiler default + + public: + virtual bool exists(const QString &rName) const; + virtual Logger *logger(const QString &rName); + virtual QList loggers() const; + // JAVA: virtual Logger *logger(const String &rName, LoggerFactory *pFactory); + virtual Logger *rootLogger() const; + virtual Level threshold() const; + virtual void setThreshold(Level level); + virtual void setThreshold(const QString &rThreshold); + + // JAVA: void clear(); + virtual bool isDisabled(Level level); + virtual void resetConfiguration(); + virtual void shutdown(); + + // JAVA: virtual void addHierarchyEventListener(HierarchyEventListener *pEventListener); + // JAVA: virtual void emitNoAppenderWarning(Logger *plogger) const; + // JAVA: virtual void fireAddAppenderEvent(Logger *plogger, Appender *pAppender) const; + + // JAVA: void addRenderer(const QString &rClass, ObjectRenderer *pObjectRenderer); + // JAVA: QHash getRendererMap() const; + // JAVA: setRenderer(const QString &rClass, ObjectRenderer *pObjectRenderer); + + protected: +#ifndef QT_NO_DEBUG_STREAM + /*! + * Writes all object member variables to the given debug stream \a rDebug and + * returns the stream. + * + * + * %Hierarchy(loggers:6 threshold:"ALL" root-level:"DEBUG" root-appenders:0) + * + * \sa QDebug, operator<<(QDebug debug, const LoggerRepository &rLoggerRepository) + */ + virtual QDebug debug(QDebug &rdebug) const; +#endif + + private: + Logger *createLogger(const QString &rName); + void resetLogger(Logger *pLogger, Level level) const; + + private: + mutable QReadWriteLock mObjectGuard; + QHash mLoggers; + volatile bool mHandleQtMessages; + Level mThreshold; + Logger *mpRootLogger; + }; + + + /************************************************************************** + * Operators, Helper + **************************************************************************/ + + + /************************************************************************** + * Inline + **************************************************************************/ + + inline Logger *Hierarchy::rootLogger() const + { // QReadLocker locker(&mObjectGuard); // Constant for object lifetime + return mpRootLogger; } + + inline Level Hierarchy::threshold() const + { // QReadLocker locker(&mObjectGuard); // Level is threadsafe + return mThreshold; } + + inline void Hierarchy::setThreshold(Level level) + { // QReadLocker locker(&mObjectGuard); // Level is threadsafe + mThreshold = level; } + + inline bool Hierarchy::isDisabled(Level level) + { // QReadLocker locker(&mObjectGuard); // Level is threadsafe + return level < mThreshold; } + + +} // namespace Log4Qt + + +// Q_DECLARE_TYPEINFO(Log4Qt::Hierarchy, Q_COMPLEX_TYPE); // Use default + + +#endif // LOG4QT_HIERARCHY_H diff --git a/src/log4qt/src/log4qt/layout.cpp b/src/log4qt/src/log4qt/layout.cpp new file mode 100644 index 0000000..160f80d --- /dev/null +++ b/src/log4qt/src/log4qt/layout.cpp @@ -0,0 +1,91 @@ +/****************************************************************************** + * + * package: Log4Qt + * file: layout.cpp + * created: September 2007 + * author: Martin Heinrich + * + * + * Copyright 2007 Martin Heinrich + * + * 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. + * + ******************************************************************************/ + + + +/****************************************************************************** + * Dependencies + ******************************************************************************/ + + +#include "log4qt/layout.h" + +#include +#include "log4qt/loggingevent.h" +#include "log4qt/logmanager.h" + + + +namespace Log4Qt +{ + + + /*************************************************************************** + * Declarations + **************************************************************************/ + + + + /************************************************************************** + * C helper functions + **************************************************************************/ + + + + /************************************************************************** + * Class implementation: Layout + **************************************************************************/ + + + QString Layout::contentType() const + { + return QString::fromLatin1("text/plain"); + } + + + void Layout::activateOptions() + { + } + + + QString Layout::endOfLine() + { + // There seams to be no function in Qt for this + +#ifdef Q_OS_WIN32 + return QLatin1String("\r\n"); +#endif // Q_OS_WIN32 +//#ifdef Q_OS_MAC +// return QLatin1String("\r"); +//#endif // Q_OS_MAC + return QLatin1String("\n"); + } + + + /************************************************************************** + * Implementation: Operators, Helper + **************************************************************************/ + + +} // namespace Log4Qt diff --git a/src/log4qt/src/log4qt/layout.h b/src/log4qt/src/log4qt/layout.h new file mode 100644 index 0000000..42f3b3e --- /dev/null +++ b/src/log4qt/src/log4qt/layout.h @@ -0,0 +1,156 @@ +/****************************************************************************** + * + * package: Log4Qt + * file: layout.h + * created: September 2007 + * author: Martin Heinrich + * + * + * Copyright 2007 Martin Heinrich + * + * 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. + * + ******************************************************************************/ + +#ifndef LOG4QT_LAYOUT_H +#define LOG4QT_LAYOUT_H + + +/****************************************************************************** + * Dependencies + ******************************************************************************/ + +#include "log4qt/helpers/logobject.h" + +#include "log4qt/helpers/logobjectptr.h" +#include "log4qt/log4qt.h" + + +/****************************************************************************** + * Declarations + ******************************************************************************/ + +namespace Log4Qt +{ + + class LoggingEvent; + + /*! + * \brief The class Layout is the base class for all layouts. + * + * \note The ownership and lifetime of objects of this class are managed. See + * \ref Ownership "Object ownership" for more details. + */ + class Layout : public LogObject + { + Q_OBJECT + + /*! + * The property holds the content type of the layout. + * + * \sa contentType() + */ + Q_PROPERTY(QString footercontentType READ contentType) + /*! + * The property holds the footer used by the layout. + * + * \sa footer(), setFooter() + */ + Q_PROPERTY(QString footer READ footer WRITE setFooter) + /*! + * The property holds the header used by the layout. + * + * \sa header(), setHeader() + */ + Q_PROPERTY(QString header READ header WRITE setHeader) + + public: + Layout(QObject *pParent = 0); + virtual ~Layout(); + private: + Layout(const Layout &rOther); // Not implemented + Layout &operator=(const Layout &rOther); // Not implemented + + public: + virtual QString contentType() const; + QString footer() const; + QString header() const; + // JAVA: virtual bool ignoresThrowable() const; + QString name() const; + void setFooter(const QString &rFooter); + void setHeader(const QString &rHeader); + void setName(const QString &rName); + // JAVA: void setIgnoresThrowable(bool) const; + + virtual void activateOptions(); + virtual QString format(const LoggingEvent &rEvent) = 0; + + /*! + * Returns the end of line seperator for the operating system. + * + * Windows: \\r\\n + * Mac: \\r + * UNIX: \\n + */ + static QString endOfLine(); + + // Member variables + private: + QString mFooter; + QString mHeader; + }; + + + /************************************************************************** + * Operators, Helper + **************************************************************************/ + + + /************************************************************************** + * Inline + **************************************************************************/ + + inline Layout::Layout(QObject *pParent) : + LogObject(pParent) + {} + + inline Layout::~Layout() + {} + + inline QString Layout::footer() const + { return mFooter; } + + inline QString Layout::header() const + { return mHeader; } + + inline QString Layout::name() const + { return objectName(); } + + inline void Layout::setFooter(const QString &rFooter) + { mFooter = rFooter; } + + inline void Layout::setHeader(const QString &rHeader) + { mHeader = rHeader; } + + inline void Layout::setName(const QString &rName) + { setObjectName(rName); } + + +} // namespace Log4Qt + + +// Q_DECLARE_TYPEINFO(Log4Qt::Layout, Q_COMPLEX_TYPE); // Use default +Q_DECLARE_TYPEINFO(Log4Qt::LogObjectPtr, Q_MOVABLE_TYPE); + + +#endif // LOG4QT_LAYOUT_H diff --git a/src/log4qt/src/log4qt/level.cpp b/src/log4qt/src/log4qt/level.cpp new file mode 100644 index 0000000..a55038f --- /dev/null +++ b/src/log4qt/src/log4qt/level.cpp @@ -0,0 +1,204 @@ +/****************************************************************************** + * + * package: Log4Qt + * file: level.cpp + * created: September 2007 + * author: Martin Heinrich + * + * + * Copyright 2007 Martin Heinrich + * + * 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. + * + ******************************************************************************/ + + + +/****************************************************************************** + * Dependencies + ******************************************************************************/ + + +#include "log4qt/level.h" + +#include +#include +#include +#include "log4qt/logger.h" + + +namespace Log4Qt +{ + + + /************************************************************************** + * Declarations + **************************************************************************/ + + + + /************************************************************************** + * C helper functions + **************************************************************************/ + + + LOG4QT_DECLARE_STATIC_LOGGER(logger, Log4Qt::Level) + + + + /************************************************************************** + * Class implementation: Level + **************************************************************************/ + + + int Level::syslogEquivalent() const + { + // QMutexLocker locker(&mObjectGuard); // Read/Write of int is safe + + switch (mValue) + { + case NULL_INT: + case ALL_INT: + case TRACE_INT: + case DEBUG_INT: + return 7; + case INFO_INT: + return 6; + case WARN_INT: + return 4; + case ERROR_INT: + return 3; + case FATAL_INT: + case OFF_INT: + return 0; + default: + Q_ASSERT_X(false, "Level::syslogEquivalent()", "Unknown level value"); + return 7; + } + } + + + QString Level::toString() const + { + // QMutexLocker locker(&mObjectGuard); // Read/Write of int is safe + + const char *p_context = "Level"; + + switch (mValue) + { + case NULL_INT: + return QCoreApplication::translate(p_context, "NULL"); + case ALL_INT: + return QCoreApplication::translate(p_context, "ALL"); + case TRACE_INT: + return QCoreApplication::translate(p_context, "TRACE"); + case DEBUG_INT: + return QCoreApplication::translate(p_context, "DEBUG"); + case INFO_INT: + return QCoreApplication::translate(p_context, "INFO"); + case WARN_INT: + return QCoreApplication::translate(p_context, "WARN"); + case ERROR_INT: + return QCoreApplication::translate(p_context, "ERROR"); + case FATAL_INT: + return QCoreApplication::translate(p_context, "FATAL"); + case OFF_INT: + return QCoreApplication::translate(p_context, "OFF"); + default: + Q_ASSERT_X(false, "Level::toString()", "Unknown level value"); + return QCoreApplication::translate(p_context, "NULL"); + } + } + + + Level Level::fromString(const QString &rLevel, bool *pOk) + { + const char *p_context = "Level"; + if (pOk) + *pOk = true; + + if (rLevel == QLatin1String("OFF") || + rLevel == QCoreApplication::translate(p_context, "OFF")) + return OFF_INT; + if (rLevel == QLatin1String("FATAL") || + rLevel == QCoreApplication::translate(p_context, "FATAL")) + return FATAL_INT; + if (rLevel == QLatin1String("ERROR") || + rLevel == QCoreApplication::translate(p_context, "ERROR")) + return ERROR_INT; + if (rLevel == QLatin1String("WARN") || + rLevel == QCoreApplication::translate(p_context, "WARN")) + return WARN_INT; + if (rLevel == QLatin1String("INFO") || + rLevel == QCoreApplication::translate(p_context, "INFO")) + return INFO_INT; + if (rLevel == QLatin1String("DEBUG") || + rLevel == QCoreApplication::translate(p_context, "DEBUG")) + return DEBUG_INT; + if (rLevel == QLatin1String("TRACE") || + rLevel == QCoreApplication::translate(p_context, "TRACE")) + return TRACE_INT; + if (rLevel == QLatin1String("ALL") || + rLevel == QCoreApplication::translate(p_context, "ALL")) + return ALL_INT; + if (rLevel == QLatin1String("NULL") || + rLevel == QCoreApplication::translate(p_context, "NULL")) + return NULL_INT; + + logger()->warn("Use of invalid level string '%1'. Using 'Level::NULL_INT' instead.", rLevel); + if (pOk) + *pOk = false; + return NULL_INT; + } + + + + /************************************************************************** + * Implementation: Operators, Helper + **************************************************************************/ + + +#ifndef QT_NO_DATASTREAM + QDataStream &operator<<(QDataStream &rStream, + const Level &rLevel) + { + quint8 l = rLevel.mValue; + rStream << l; + return rStream; + } + + + QDataStream &operator>>(QDataStream &rStream, + Level &rLevel) + { + quint8 l; + rStream >> l; + rLevel.mValue = (Level::Value)l; + return rStream; + } +#endif // QT_NO_DATASTREAM + + +#ifndef QT_NO_DEBUG_STREAM + QDebug operator<<(QDebug debug, + const Level &rLevel) + { + debug.nospace() << "Level(" + << rLevel.toString() + << ")"; + return debug.space(); + } +#endif // QT_NO_DEBUG_STREAM + + +} // namespace Log4Qt diff --git a/src/log4qt/src/log4qt/level.h b/src/log4qt/src/log4qt/level.h new file mode 100644 index 0000000..93914c2 --- /dev/null +++ b/src/log4qt/src/log4qt/level.h @@ -0,0 +1,193 @@ +/****************************************************************************** + * + * package: Log4Qt + * file: level.h + * created: September 2007 + * author: Martin Heinrich + * + * + * Copyright 2007 Martin Heinrich + * + * 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. + * + ******************************************************************************/ + +#ifndef LOG4QT_LEVEL_H +#define LOG4QT_LEVEL_H + + +/****************************************************************************** + * Dependencies + ******************************************************************************/ + +#include +#include +#include "log4qt/log4qt.h" + + +/****************************************************************************** + * Declarations + ******************************************************************************/ + +namespace Log4Qt +{ + + /*! + * \brief The class Level defines the level of a logging event. + * + * \note All the functions declared in this class are thread-safe. + */ + class Level + { + public: + // Comparisson operators rely on the order: + // NULL_INT < ALL_INT < TRACE_INT < ... + // Serialisation uses unsigned 8 bit int + + /*! + * The enumeration Value contains all possible Level values. + */ + enum Value + { + /*! NULL_INT is used for no level has been specified */ + NULL_INT = 0, + ALL_INT = 32, + TRACE_INT = 64, + DEBUG_INT = 96, + INFO_INT = 128, + WARN_INT = 150, + ERROR_INT = 182, + FATAL_INT = 214, + OFF_INT = 255 + }; + + public: + Level(Value value = NULL_INT); + // Level(const Level &rOther); // Use compiler default + // virtual ~Level(); // Use compiler default + // Level &operator=(const Level &rOther); // Use compiler default + + int syslogEquivalent() const; + int toInt() const; + + bool operator==(const Level &rOther) const; + bool operator!=(const Level &rOther) const; + bool operator<(const Level &rOther) const; + bool operator<=(const Level &rOther) const; + bool operator>(const Level &rOther) const; + bool operator>=(const Level &rOther) const; + QString toString() const; + + static Level fromString(const QString &rName, bool *pOk = 0); + + private: + // QMutex mObjectGuard; + volatile Value mValue; + +#ifndef QT_NO_DATASTREAM + // Needs to be friend to stream objects + friend QDataStream &operator<<(QDataStream &rStream, + const Level &rLevel); + friend QDataStream &operator>>(QDataStream &rStream, + Level &rLevel); +#endif // QT_NO_DATASTREAM + }; + + + /************************************************************************** + * Operators, Helper + **************************************************************************/ + +#ifndef QT_NO_DATASTREAM + /*! + * \relates Level + * + * Writes the given error \a rLevel to the given stream \a rStream, + * and returns a reference to the stream. + */ + QDataStream &operator<<(QDataStream &rStream, + const Level &rLevel); + + /*! + * \relates Level + * + * Reads an error from the given stream \a rStream into the given + * error \a rLevel, and returns a reference to the stream. + */ + QDataStream &operator>>(QDataStream &rStream, + Level &rLevel); +#endif // QT_NO_DATASTREAM + +#ifndef QT_NO_DEBUG_STREAM + /*! + * \relates Level + * + * Writes all object member variables to the given debug stream \a rDebug + * and returns the stream. + * + * + * %Level("ERROR") + * + * \sa QDebug + */ + QDebug operator<<(QDebug debug, + const Level &rLevel); +#endif // QT_NO_DEBUG_STREAM + + + /************************************************************************** + * Inline + **************************************************************************/ + + + inline Level::Level(Value value) : + mValue(value) + {} + + inline int Level::toInt() const + { // QMutexLocker locker(&mObjectGuard); // Read/Write of int is safe + return mValue; } + + inline bool Level::operator==(const Level &rOther) const + { // QMutexLocker locker(&mObjectGuard); // Read/Write of int is safe + return mValue == rOther.mValue; } + + inline bool Level::operator!=(const Level &rOther) const + { // QMutexLocker locker(&mObjectGuard); // Read/Write of int is safe + return mValue != rOther.mValue; } + + inline bool Level::operator<(const Level &rOther) const + { // QMutexLocker locker(&mObjectGuard); // Read/Write of int is safe + return mValue < rOther.mValue; } + + inline bool Level::operator<=(const Level &rOther) const + { // QMutexLocker locker(&mObjectGuard); // Read/Write of int is safe + return mValue <= rOther.mValue; } + + inline bool Level::operator>(const Level &rOther) const + { // QMutexLocker locker(&mObjectGuard); // Read/Write of int is safe + return mValue > rOther.mValue; } + + inline bool Level::operator>=(const Level &rOther) const + { // QMutexLocker locker(&mObjectGuard); // Read/Write of int is safe + return mValue >= rOther.mValue; } + + +} // namespace Log4Qt + + +Q_DECLARE_METATYPE(Log4Qt::Level) +Q_DECLARE_TYPEINFO(Log4Qt::Level, Q_MOVABLE_TYPE); + + +#endif // LOG4QT_LEVEL_H diff --git a/src/log4qt/src/log4qt/log4qt.cpp b/src/log4qt/src/log4qt/log4qt.cpp new file mode 100644 index 0000000..9378f46 --- /dev/null +++ b/src/log4qt/src/log4qt/log4qt.cpp @@ -0,0 +1,58 @@ +/****************************************************************************** + * + * package: Log4Qt + * file: logging.cpp + * created: September 2007 + * author: Martin Heinrich + * + * + * Copyright 2007 Martin Heinrich + * + * 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. + * + *****************************************************************************/ + + + +/****************************************************************************** + *Dependencies + ******************************************************************************/ + + +#include "log4qt/log4qt.h" + + + +namespace Log4Qt +{ + + + /************************************************************************** + * Declarations + **************************************************************************/ + + + + /************************************************************************** + * C helper functions + **************************************************************************/ + + + + /************************************************************************** + *Implementation: Operators, Helper + **************************************************************************/ + + + +} // namespace Log4Qt diff --git a/src/log4qt/src/log4qt/log4qt.h b/src/log4qt/src/log4qt/log4qt.h new file mode 100644 index 0000000..73c3cfe --- /dev/null +++ b/src/log4qt/src/log4qt/log4qt.h @@ -0,0 +1,614 @@ +/****************************************************************************** + * + * package: Log4Qt + * file: logging.h + * created: September 2007 + * author: Martin Heinrich + * + * + * changes: Sep 2008, Martin Heinrich: + * - Added a compile time version check for the Qt version + * Jan 2009, Martin Heinrich: + * - Updated documentation and version information for version 0.2 + * Feb 2009, Martin Heinrich: + * - Updated version information for version 0.3 + * + * + * Copyright 2007 - 2009 Martin Heinrich + * + * 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. + * + ******************************************************************************/ + +#ifndef LOG4QT_H +#define LOG4QT_H + + +/*! + * \mainpage + * + * %Log4Qt is a C++ port of the Apache Software Foundation Log4j package + * using the Trolltech Qt Framework. + * + * The documentation describes classes and methods that have been added or + * changed compared to Log4j. + * + * The following sections are describing the implementation in more detail: + * - \ref Changes "Differences to Log4j" + * - \ref Ownership "Object ownership" + * - \ref LogLog "Logging within the package" + * - \ref Init "Initialization procedure" + * - \ref Env "Environment Variables" + * - \ref Undocumented "Undocumented functions" + * - \ref Assumptions "Assumptions" + * + * \author Martin Heinrich + * \version 0.3 (January 2009) + * + */ + +/*! + * \page Changes Differences to Log4j + * + * The following fundamental differences exist between %Log4Qt and Log4j: + * + * - As a JAVA package Log4j does not have to manage object ownership and + * lifetime in the same way then it is required in C++. For details on + * how object ownership is handled see \ref Ownership "Object ownership". + * - The package uses itself for its internal logging similar to Log4j 1.3. + * For details see \ref LogLog "Logging within the package". + * - The configuration using system properties was replaced with a combination + * of environment variables and application settings. For details see + * \ref Env "Environment Variables". + * - Custom levels are not supported. + * - Multiple Logger Repositories are not supported + * + * The following classes have been changed: + * + * - \ref Log4Qt::AppenderSkeleton "AppenderSkeleton" + * - The procedure of checking, if logging is possible, originally used by + * \ref Log4Qt::WriterAppender "WriterAppender" was generalised and is used + * in \ref Log4Qt::AppenderSkeleton "AppenderSkeleton" and derived classes + * (\ref Log4Qt::AppenderSkeleton::checkEntryConditions() "checkEntryConditions()"). + * - The \ref Log4Qt::AppenderSkeleton::doAppend() "doAppend()" member function will + * check the entry conditions by calling the sub-class specific + * \ref Log4Qt::AppenderSkeleton::checkEntryConditions() "checkEntryConditions()". + * If successful the sub-class specific + * \ref Log4Qt::AppenderSkeleton::append() "append()" function is called. + * + * - Configurator + * - Configure functions return a boolean indicating, if the configuration + * was successful. + * - Configure errors are accessible over + * \ref Log4Qt::ConfiguratorHelper::configureError() + * "ConfiguratorHelper::configureError()". + * - Watching for configuration file changes is a function performed + * centrally by the \ref Log4Qt::ConfiguratorHelper "ConfiguratorHelper". + * The class provides signals to notify on configuration change and errors. + * - The class \ref Log4Qt::PropertyConfigurator "PropertyConfigurator" was + * extended to be able to read configuration data from a QSettings object. + * + * - \ref Log4Qt::Level "Level" + * - A new value \ref Log4Qt::Level::NULL_INT "Level::NULL_INT" was + * introduced to indicate there is no level set. + * + * - \ref Log4Qt::Logger "Logger" + * - The method \ref Log4Qt::Logger::isEnabledFor() "isEnabledFor()" + * does also take the repository threshold into account. + * - Several overloaded convenience member function are available to log + * messages with arguments of different types. + * - Two macros, \ref Log4Qt::LOG4QT_DECLARE_STATIC_LOGGER "LOG4QT_DECLARE_STATIC_LOGGER" + * and \ref Log4Qt::LOG4QT_DECLARE_QCLASS_LOGGER "LOG4QT_DECLARE_QCLASS_LOGGER", + * allows retrieving and caching of a pointer to a logger object. + * + * - \ref Log4Qt::LogManager "LogManager" + * - A QtMessage handler can be installed via + * \ref Log4Qt::LogManager::setHandleQtMessages() "setHandleQtMessages()", + * to redirect all messages created by calls to qDebug(), qWarning(), + * qCritical() and qFatal() to a logger. The logger is named Qt and can be + * accessed using \ref Log4Qt::LogManager::qtLogger() "qtLogger()". + * - The initialisation procedure is available over a public method + * (\ref Log4Qt::LogManager::startup() "startup()"). + * - The LogManager provides access to the logger used internally by the + * package (\ref Log4Qt::LogManager::logLogger() "logLogger()") and to + * its default initialisation procedure + * (\ref Log4Qt::LogManager::configureLogLogger() "configureLogLogger()"). + * + * - \ref Log4Qt::WriterAppender "WriterAppender" + * - The class will call \ref Log4Qt::WriterAppender::handleIoErrors() + * "handleIoErrors()" after all I/O operations. Sub-classes should + * re-implement the function to handle errors. + * + * The following classes have been added: + * + * - An additional appender class, \ref Log4Qt::DebugAppender "DebugAppender", + * was added. The class appends logging events to the platform specific debug + * output. + * - Various helper class have been introduced: + * - \ref Log4Qt::ClassLogger "ClassLogger": The class ClassLogger provides + * logging for a QObject derived class. + * - \ref Log4Qt::ConfiguratorHelper "ConfiguratorHelper": The class + * ConfiguratorHelper provides a configuration file watch and last error + * for configurator classes. + * - \ref Log4Qt::DateTime "DateTime": The class DateTime provides extended + * functionality for QDateTime. + * - \ref Log4Qt::LogError "LogError": The class LogError represents an error. + * - \ref Log4Qt::Factory "Factory": The class Factory provides factories + * for Appender, Filter and Layout objects. + * - \ref Log4Qt::InitialisationHelper "InitialisationHelper": The class + * InitialisationHelper performs static initialisation tasks. + * - \ref Log4Qt::LogObject "LogObject": The class LogObject is the common + * base class for many classes in the package. + * - \ref Log4Qt::LogObjectPtr "LogObjectPtr": The class LogObjectPtr + * implements automatic reference counting for LogObject objects. + * - \ref Log4Qt::PatternFormatter "PatternFormatter": The class + * PatternFormatter formats a logging event based on a pattern string. + * - \ref Log4Qt::Properties "Properties": The class Properties implements a + * JAVA property hash. + */ + +/*! + * \page Ownership Object ownership + * + * In difference to the JAVA Log4j package %Log4Qt must manage ownership and + * lifetime of the objects used. This is non trivial as objects are created + * and used in different ways. + * + * In general an object can be created explicitly for example an application + * may create Loggers, Appenders and Layouts during creation of a QApplication + * object. But they can also be automatically created by the package on + * startup using a \ref Log4Qt::PropertyConfigurator "PropertyConfigurator" + * configuration file. Objects may also be created the one way and then used + * the other. Object may be used by multiple other objects. A Layout for example + * may be used by multiple Appenders. Objects are also created from multiple + * threads. The creation may happen during static initialisation and the + * deletion during static de-initialization. + * + * The parent child model used by QObject cannot be used to handle this. It + * cannot automatically delete an object that is used by multiple others as + * for example an Appender used by multiple Loggers. In addition to this + * QObjects and their children must reside in the same thread. This would + * either mean to impose restriction on how objects can be created or to move + * objects to a specific thread. + * + * To allow an automatic deletion of not required objects the package + * implements reference counting for Appenders, Layouts and Filters. The + * reference counting is implemented in \ref Log4Qt::LogObject "LogObject", + * which is used as a common base class. The reference count can be explicitly + * changed using the methods \ref Log4Qt::LogObject::retain() "retain()" and + * \ref Log4Qt::LogObject::release() "release()". Alternatively an auto pointer + * is available \ref Log4Qt::LogObjectPtr "LogObjectPtr", which is used + * throughout the package. + * + * The reference counting mechanism will test, if an object has a QObject + * parent object set. If a parent is set, the object will not be deleted, if + * the reference count reaches 0. This allows to mix the reference counted + * paradigm with the QObject parent child one. + * + * The following example configures a logger and uses reference counting to + * manage the ownership of objects. + * + * \code + * // Create layout + * TTCCLayout *p_layout = new TTCCLayout(); + * + * // Create appender + * ConsoleAppender *p_appender = new ConsoleAppender(p_layout, ConsoleAppender::STDOUT_TARGET); + * p_appender->activateOptions(); + * + * // Get logger + * Logger *p_logger = Logger::logger("MyClass"); + * p_logger->addAppender(p_appender); + * + * // ... + * + * // Remove appender from Logger + * p_logger->removeAllAppenders(); // p_appender and p_layout are deleted here + * \endcode + * + * The following example configures a logger and uses QObject ownership of + * objects. + * + * \code + * QObject *p_parent = new MyObject; + * + * // Create objects + * ConsoleAppender *p_appender = new ConsoleAppender(p_parent); + * TTCCLayout *p_layout = new TTCCLayout(p_appender); + * + * // Configure appender + * p_appender->setTarget(ConsoleAppender::STDOUT_TARGET); + * p_appender->setLayout(p_layout); + * p_appender->activateOptions(); + * + * // Get logger + * Logger *p_logger = Logger::logger("MyClass"); + * p_logger->addAppender(p_appender); + * + * // ... + * + * // Remove appender from Logger + * p_logger->removeAllAppenders(); + * + * delete p_parent; // p_appender and p_layout are deleted here + * \endcode + * + * The following example shows how to use objects created on the stack. + * + * \code + * { + * // Create layout + * TTCCLayout layout; + * layout.retain(); + * + * // Create appender + * ConsoleAppender appender(&layout, ConsoleAppender::STDOUT_TARGET); + * appender.retain(); + * appender.activateOptions(); + * + * // Get logger + * Logger *p_logger = Logger::logger("MyClass"); + * p_logger->addAppender(&appender); + * + * // ... + * + * // Remove appender from Logger + * p_logger->removeAllAppenders(); // Without retain() program crashes here + * + * } // p_appender and p_layout are deleted here + * \endcode + */ + +/*! + * \page LogLog Logging within the package + * + * The package uses itself for logging similar to Log4j 1.3. This brings much + * more flexibility over logging to stdout, stderr like in Log4j 1.2 using + * logLog. It also enables the program to capture and handle errors raised by + * the package. + * + * Using this approach introduces the issue of recursion. The following example + * explains a situation where this happens. Let's say all logger are configured + * to be additive and only the root logger has an appender set. The appender + * is a \ref Log4Qt::FileAppender "FileAppender". During the logging of an + * event an I/O error occurs. The \ref Log4Qt::FileAppender "FileAppender" logs + * an event by itself using the logger %Log4Qt::FileAppender. The event is + * passed to the root logger, which calls then the \ref Log4Qt::FileAppender + * "FileAppender". This causes another I/O error, which is logged by + * the \ref Log4Qt::FileAppender "FileAppender". + * + * To avoid an endless loop the appender will drop the event on a recursive + * invocation. This check is done by \ref Log4Qt::AppenderSkeleton + * "AppenderSkeleton" in \ref Log4Qt::AppenderSkeleton::doAppend() + * "doAppend()". + * + * The problem only occurs, if a logger, appender, layout or filter log an + * event while an event is appended. Neither the logger class nor any of the + * layout or filter classes log events during appending of an event. Most of + * the appender classes may log errors during appending. Only the + * \ref Log4Qt::ListAppender "ListAppender" and + * \ref Log4Qt::ListAppender "ConsoleAppender" are not logging events. + * + * The default configuration uses two \ref Log4Qt::ListAppender + * "ConsoleAppender", one for stderr and one for stdout. No event will be + * dropped, because no recursive invocations can occur. + */ + +/*! + * \page Init Initialization procedure + * + * The package is initialised in two stages. The first stage takes place during + * static initialization. The second stage takes place when the + * \ref Log4Qt::LogManager "LogManager" singleton is created. + * + * During static initialisation the \ref Log4Qt::InitialisationHelper + * "InitialisationHelper" singleton is created . On construction it captures + * the program startup time, reads the required values from the system + * environment and registers the package types with the Qt type system. + * + * The \ref Log4Qt::LogManager "LogManager" singleton is created on first use. + * The creation is usually triggered by the request for a \ref Log4Qt::Logger + * "Logger" object. The call to \ref Log4Qt::Logger::logger() + * "Logger::logger()" is passed through to \ref Log4Qt::LogManager::logger() + * "LogManager::logger()". On creation the \ref Log4Qt::LogManager "LogManager" + * creates a \ref Log4Qt::Hierarchy "Hierarchy" object as logger repository. + * + * After the singleton is created the logging of the package is configured to + * its default by a call to \ref Log4Qt::LogManager::configureLogLogger() + * "LogManager::configureLogLogger()". The logger + * \ref Log4Qt::LogManager::logLogger() "logLogger()" is configured to be not + * additive. Messages with the level \ref Log4Qt::Level::ERROR_INT + * "Level::ERROR_INT" and \ref Log4Qt::Level::FATAL_INT "Level::FATAL_INT" are + * written to \c stderr using a ConsoleAppender. The remaining messages are + * written to \c stdout using a second ConsoleAppender. The level is read from + * the system environment or application settings using + * \ref Log4Qt::InitialisationHelper::setting() + * "InitialisationHelper::setting()" with the key \c Debug. If a level value + * is found, but it is not a valid Level string, + * \ref Log4Qt::Level::DEBUG_INT "Level::DEBUG_INT" is used. If no level string + * is found \ref Log4Qt::Level::ERROR_INT "Level::ERROR_INT" is used. + * + * Once the logging is configured the package is initialised by a call to + * \ref Log4Qt::LogManager::startup() "LogManager::startup()". The function + * will test for the setting \c DefaultInitOverride in the system environment + * and application settings using \ref Log4Qt::InitialisationHelper::setting() + * "InitialisationHelper::setting()". If the value is present and set to + * anything else then \c false, the initialisation is aborted.
+ * The system environment and application settings are tested for the setting + * \c Configuration. If it is found and it is a valid path to a file, the + * package is configured with the file using + * \ref Log4Qt::PropertyConfigurator::doConfigure(const QString &, LoggerRepository *) + * "PropertyConfigurator::doConfigure()". If the setting \c Configuration is + * not available and a QCoreApplication object is present, the application + * settings are tested for a group \c Log4Qt/Properties. If the group exists, + * the package is configured with the setting using the + * \ref Log4Qt::PropertyConfigurator::doConfigure(const QSettings &r, LoggerRepository *) + * "PropertyConfiguratordoConfigure()". If neither a configuration file nor + * configuration settings could be found, the current working directory is + * searched for the file \c "log4qt.properties". If it is found, the package + * is configured with the file using + * \ref Log4Qt::PropertyConfigurator::doConfigure(const QString &, LoggerRepository *) + * "PropertyConfigurator::doConfigure()". + * + * The following example shows how to use application settings to initialise the + * package. + * + * \code + * # file: myapplication.h + * + * #include qapplication.h + * + * class MyApplication : public QApplication + * { + * Q_OBJECT + * + * public: + * MyApplication(); + * ~MyApplication(); + * void setupLog4Qt(); + * } + * \endcode + * \code + * # file: myapplication.cpp + * + * #include myapplication.h + * + * MyApplication::MyApplication( + * { + * // Set Application data to allow Log4Qt initialisation to read the + * // correct values + * setApplicationName("MyApplication"); + * setOrganisationName("MyOrganisation"); + * setOrganizationDomain("www.myorganisation.com"); + * + * // Log first message, which initialises Log4Qt + * Log4Qt::Logger::logger("MyApplication")->info("Hello World"); + * } + * + * MyApplication::~MyApplication() + * { + * } + * + * void MyApplication::setupLog4Qt() + * { + * QSettings s; + * + * // Set logging level for Log4Qt to TRACE + * s.beginGroup("Log4Qt"); + * s.setValue("Debug", "TRACE"); + * + * // Configure logging to log to the file C:/myapp.log using the level TRACE + * s.beginGroup("Properties"); + * s.setValue("log4j.appender.A1", "org.apache.log4j.FileAppender"); + * s.setValue("log4j.appender.A1.file", "C:/myapp.log"); + * s.setValue("log4j.appender.A1.layout", "org.apache.log4j.TTCCLayout"); + * s.setValue("log4j.appender.A1.layout.DateFormat", "ISO8601"); + * s.setValue("log4j.rootLogger", "TRACE, A1"); + * + * // Settings will become active on next application startup + * } + * \endcode + */ + +/*! + * \page Env Environment Variables + * + * The package uses environment variables to control the initialization + * procedure. The environment variables replace the system property entries + * used by Log4j. + * + * For compability reasons the Log4j entry is recognised. Alternatively a + * environment variable style Log4Qt form can be used. The following entries + * are used: + * + * - LOG4QT_DEBUG
+ * The variable controls the \ref Log4Qt::Level "Level" value for the + * logger \ref Log4Qt::LogManager::logLogger() "LogManager::logLogger()". + * If the value is a valid \ref Log4Qt::Level "Level" string, the level for + * the is set to the level. If the value is not a valid + * \ref Log4Qt::Level "Level" string, \ref Log4Qt::Level::DEBUG_INT + * "DEBUG_INT" is used. Otherwise \ref Log4Qt::Level::ERROR_INT "ERROR_INT" + * is used. + * - \ref Log4Qt::LogManager::configureLogLogger() + * "LogManager::configureLogLogger()" + * + * - LOG4QT_DEFAULTINITOVERRIDE
+ * The variable controls the \ref Init "initialization procedure" performed + * by the \ref Log4Qt::LogManager "LogManager" on startup. If it is set to + * any other value then \c false the \ref Init "initialization procedure" + * is skipped. + * - \ref Log4Qt::LogManager::startup() "LogManager::startup()" + * + * - LOG4QT_CONFIGURATION
+ * The variable specifies the configuration file used for initialising the + * package. + * - \ref Log4Qt::LogManager::startup() "LogManager::startup()" + * + * - LOG4QT_CONFIGURATORCLASS
+ * The variable specifies the configurator class used for initialising the + * package. + * + * Environment variables are read during static initialisation on creation of + * the \ref Log4Qt::InitialisationHelper "InitialisationHelper". They can be + * accessed by calling \ref Log4Qt::InitialisationHelper::environmentSettings() + * "InitialisationHelper::environmentSettings()". + * + * All settings can also be made in the application settings under the group + * \c %Log4Qt. For example the environment variable \c LOG4QT_DEBUG is + * equivalent to the setting \c Log4Qt/Debug. If an environment variable is + * set it takes precedence over the application setting. Settings are only + * used, if an QApplication object is available, when the + * \ref Log4Qt::LogManager "LogManager" is + * initialised (see \ref Log4Qt::InitialisationHelper::setting() + * "InitialisationHelper::setting()" for details). + */ + +/*! + * \page Undocumented Undocumented functions + * + * In general it was tried to avoid the usage of undocumented features of Qt. + * Nice to have features like for example Q_DECLARE_PRIVATE are not used. Only + * features that would have been resulted in re-coding the same functionality + * are used. + * + * - QT_WA: The macro is used to call Windows A/W functions + * - \ref Log4Qt::DebugAppender "DebugAppender" + * - QBasicAtomicPointer: The class is used instead of QAtomicPointer, because + * it allows the initialisation as plain old data type. + * - \ref Log4Qt::LOG4QT_GLOBAL_STATIC "LOG4QT_GLOBAL_STATIC" + * - \ref Log4Qt::LOG4QT_IMPLEMENT_INSTANCE "LOG4QT_IMPLEMENT_INSTANCE" + * - \ref Log4Qt::LOG4QT_DECLARE_STATIC_LOGGER "LOG4QT_DECLARE_STATIC_LOGGER" + * - Q_BASIC_ATOMIC_INITIALIZER: The macro is used to initialise QAtomicPointer + * objects as plain old data type. + * - \ref Log4Qt::LOG4QT_GLOBAL_STATIC "LOG4QT_GLOBAL_STATIC" + * - \ref Log4Qt::LOG4QT_IMPLEMENT_INSTANCE "LOG4QT_IMPLEMENT_INSTANCE" + * - \ref Log4Qt::LOG4QT_DECLARE_STATIC_LOGGER "LOG4QT_DECLARE_STATIC_LOGGER" + */ + +/*! + * \page Assumptions Assumptions + * + * The following assumptions are used throughout the package: + * + * - Reading / writing of bool or int is thread-safe, if declared volatile + * - \ref Log4Qt::ListAppender "ListAppender" + * - \ref Log4Qt::AppenderSkeleton "AppenderSkeleton" + * - \ref Log4Qt::ConsoleAppender "ConsoleAppender" + * - \ref Log4Qt::FileAppender "FileAppender" + * - \ref Log4Qt::Hierarchy "Hierarchy" + * - \ref Log4Qt::Level "Level" + * - \ref Log4Qt::Logger "Logger" + * - \ref Log4Qt::WriterAppender "WriterAppender" + * - \ref Log4Qt::Layout::format() "Layout::format()" is implemented reentrant + * in all sub-classes. + * - \ref Log4Qt::AppenderSkeleton "AppenderSkeleton" + * - Being able to use singleton objects during static de-initialization without + * order issues is more valuable then their destruction. + * - \ref Log4Qt::LogManager "LogManager" + * - \ref Log4Qt::LOG4QT_GLOBAL_STATIC "LOG4QT_GLOBAL_STATIC" + * - \ref Log4Qt::LOG4QT_IMPLEMENT_INSTANCE "LOG4QT_IMPLEMENT_INSTANCE" + */ + +/****************************************************************************** + * Dependencies + ******************************************************************************/ + +#include + +#if QT_VERSION < QT_VERSION_CHECK(4, 3, 0) +# error "Log4Qt requires Qt version 4.3.0 or higher" +#endif + + +/****************************************************************************** + * Declarations + ******************************************************************************/ + +/*! + * \brief The namespace %Log4Qt encloses all parts of the package. + */ +namespace Log4Qt +{ + /*! + * This macro expands a numeric value of the form 0xMMmmPP (MM = major, + * mm = minor, PP = patch) that specifies Log4Qt's version number. + * This is the version against which the application is compiled. + * + * \sa \ref Log4Qt::LOG4QT_VERSION_STR "LOG4QT_VERSION_STR", + * \ref Log4Qt::LogManager::version() "LogManager::version()" + */ + #define LOG4QT_VERSION 0x000200 + + /*! + * The macro expands to a string that specifies the Log4Qt's version + * number. This is the version against which the application is compiled. + * + * \sa \ref Log4Qt::LOG4QT_VERSION "LOG4QT_VERSION", + * \ref Log4Qt::LogManager::version() "LogManager::version()" + */ + #define LOG4QT_VERSION_STR "0.3.0" + + enum ErrorCode + { + OK = 0, + // AppenderSkeleton, FileAppender, WriterAppender + APPENDER_ACTIVATE_MISSING_LAYOUT_ERROR, + APPENDER_ACTIVATE_MISSING_WRITER_ERROR, + APPENDER_ACTIVATE_MISSING_FILE_ERROR, + APPENDER_CLOSED_ERROR, + APPENDER_INVALID_PATTERN_ERROR, + APPENDER_NO_OPEN_FILE_ERROR, + APPENDER_NOT_ACTIVATED_ERROR, + APPENDER_OPENING_FILE_ERROR, + APPENDER_RENAMING_FILE_ERROR, + APPENDER_REMOVE_FILE_ERROR, + APPENDER_USE_INVALID_PATTERN_ERROR, + APPENDER_USE_MISSING_LAYOUT_ERROR, + APPENDER_USE_MISSING_WRITER_ERROR, + APPENDER_WRITING_FILE_ERROR, + // Level + LEVEL_INVALID_LEVEL_STRING, + // Layouts, PatternFormatter + LAYOUT_EXPECTED_DIGIT_ERROR, + LAYOUT_OPTION_IS_NOT_INTEGER_ERROR, + LAYOUT_INTEGER_IS_NOT_POSITIVE_ERROR, + // Logger + LOGGER_INVALID_LEVEL_FOR_ROOT, + // PropertyConfigurator, OptionHandler + CONFIGURATOR_OPENING_FILE_ERROR, + CONFIGURATOR_READING_FILE_ERROR, + CONFIGURATOR_INVALID_SUBSTITUTION_ERROR, + CONFIGURATOR_INVALID_OPTION_ERROR, + CONFIGURATOR_MISSING_APPENDER_ERROR, + CONFIGURATOR_UNKNOWN_APPENDER_CLASS_ERROR, + CONFIGURATOR_MISSING_LAYOUT_ERROR, + CONFIGURATOR_UNKNOWN_LAYOUT_CLASS_ERROR, + CONFIGURATOR_PROPERTY_ERROR, + CONFIGURATOR_UNKNOWN_TYPE_ERROR + }; + + + /****************************************************************************** + * Operators, Helpers + ******************************************************************************/ + + + /****************************************************************************** + * Inline + ******************************************************************************/ + + +} // namespace Log4Qt + + +#endif // LOG4QT_H diff --git a/src/log4qt/src/log4qt/log4qt.pri b/src/log4qt/src/log4qt/log4qt.pri new file mode 100644 index 0000000..f9730b9 --- /dev/null +++ b/src/log4qt/src/log4qt/log4qt.pri @@ -0,0 +1,111 @@ +# ******************************************************************************* +# +# package: Log4Qt +# file: log4qt.pri +# created: September 2007 +# author: Martin Heinrich +# +# +# Copyright 2007 Martin Heinrich +# +# 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. +# +# ******************************************************************************* + +INCLUDEPATH += $$PWD/.. +DEPENDPATH += $$PWD/.. +HEADERS += \ + $$PWD/appender.h \ + $$PWD/appenderskeleton.h \ + $$PWD/basicconfigurator.h \ + $$PWD/consoleappender.h \ + $$PWD/dailyrollingfileappender.h \ + $$PWD/fileappender.h \ + $$PWD/helpers/classlogger.h \ + $$PWD/helpers/configuratorhelper.h \ + $$PWD/helpers/datetime.h \ + $$PWD/helpers/factory.h \ + $$PWD/helpers/initialisationhelper.h \ + $$PWD/helpers/logerror.h \ + $$PWD/helpers/logobject.h \ + $$PWD/helpers/logobjectptr.h \ + $$PWD/helpers/optionconverter.h \ + $$PWD/helpers/patternformatter.h \ + $$PWD/helpers/properties.h \ + $$PWD/hierarchy.h \ + $$PWD/layout.h \ + $$PWD/level.h \ + $$PWD/log4qt.h \ + $$PWD/logger.h \ + $$PWD/loggerrepository.h \ + $$PWD/loggingevent.h \ + $$PWD/logmanager.h \ + $$PWD/mdc.h \ + $$PWD/ndc.h \ + $$PWD/patternlayout.h \ + $$PWD/propertyconfigurator.h \ + $$PWD/rollingfileappender.h \ + $$PWD/simplelayout.h \ + $$PWD/spi/filter.h \ + $$PWD/ttcclayout.h \ + $$PWD/writerappender.h \ + $$PWD/varia/debugappender.h \ + $$PWD/varia/denyallfilter.h \ + $$PWD/varia/nullappender.h \ + $$PWD/varia/levelmatchfilter.h \ + $$PWD/varia/levelrangefilter.h \ + $$PWD/varia/listappender.h \ + $$PWD/varia/stringmatchfilter.h + +SOURCES += \ + $$PWD/appenderskeleton.cpp \ + $$PWD/basicconfigurator.cpp \ + $$PWD/consoleappender.cpp \ + $$PWD/dailyrollingfileappender.cpp \ + $$PWD/fileappender.cpp \ + $$PWD/helpers/classlogger.cpp \ + $$PWD/helpers/configuratorhelper.cpp \ + $$PWD/helpers/datetime.cpp \ + $$PWD/helpers/factory.cpp \ + $$PWD/helpers/initialisationhelper.cpp \ + $$PWD/helpers/logerror.cpp \ + $$PWD/helpers/logobject.cpp \ + $$PWD/helpers/logobjectptr.cpp \ + $$PWD/helpers/optionconverter.cpp \ + $$PWD/helpers/patternformatter.cpp \ + $$PWD/helpers/properties.cpp \ + $$PWD/hierarchy.cpp \ + $$PWD/layout.cpp \ + $$PWD/level.cpp \ + $$PWD/log4qt.cpp \ + $$PWD/logger.cpp \ + $$PWD/loggerrepository.cpp \ + $$PWD/loggingevent.cpp \ + $$PWD/logmanager.cpp \ + $$PWD/mdc.cpp \ + $$PWD/ndc.cpp \ + $$PWD/patternlayout.cpp \ + $$PWD/propertyconfigurator.cpp \ + $$PWD/rollingfileappender.cpp \ + $$PWD/simplelayout.cpp \ + $$PWD/spi/filter.cpp \ + $$PWD/ttcclayout.cpp \ + $$PWD/writerappender.cpp \ + $$PWD/varia/debugappender.cpp \ + $$PWD/varia/denyallfilter.cpp \ + $$PWD/varia/nullappender.cpp \ + $$PWD/varia/levelmatchfilter.cpp \ + $$PWD/varia/levelrangefilter.cpp \ + $$PWD/varia/listappender.cpp \ + $$PWD/varia/stringmatchfilter.cpp + \ No newline at end of file diff --git a/src/log4qt/src/log4qt/logger.cpp b/src/log4qt/src/log4qt/logger.cpp new file mode 100644 index 0000000..d5dc936 --- /dev/null +++ b/src/log4qt/src/log4qt/logger.cpp @@ -0,0 +1,349 @@ +/****************************************************************************** + * + * package: Log4Qt + * file: logger.cpp + * created: September 2007 + * author: Martin Heinrich + * + * + * changes: Sep 2008, Martin Heinrich: + * - Fixed problem in Qt 4.4 where QReadWriteLock is by default + * non-recursive. + * + * + * Copyright 2007 - 2008 Martin Heinrich + * + * 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. + * + ******************************************************************************/ + + + +/****************************************************************************** + * Dependencies + ******************************************************************************/ + + +#include "log4qt/logger.h" + +#include +#include "log4qt/appenderskeleton.h" +#include "log4qt/varia/listappender.h" +#include "log4qt/loggingevent.h" +#include "log4qt/log4qt.h" +#include "log4qt/loggerrepository.h" +#include "log4qt/logmanager.h" + + +namespace Log4Qt +{ + + + /************************************************************************** + * Declarations + **************************************************************************/ + + + + /************************************************************************** + * C helper functions + **************************************************************************/ + + + + /************************************************************************** + * Class implementation: Logger + **************************************************************************/ + + + Logger::Logger(LoggerRepository* pLoggerRepository, Level level, const QString &rName, Logger *pParent) : + QObject(0), +#if QT_VERSION < QT_VERSION_CHECK(4, 4, 0) + mObjectGuard(), +#else + mObjectGuard(QReadWriteLock::Recursive), +#endif + mName(rName), + mpLoggerRepository(pLoggerRepository), + mAdditivity(true), + mAppenders(), + mLevel(level), + mpParent(pParent) + { + Q_ASSERT_X(pLoggerRepository, "Logger::Logger()", "Construction of Logger with null LoggerRepository"); + + setObjectName(mName); + } + + + Logger::~Logger() + { + logger()->warn("Unexpected destruction of Logger"); + + // QWriteLocker locker(&mObjectGuard); + // + // QMutableListIterator< LogObjectPtr > i(mAppenders); + // while (i.hasNext()) + // { + // i.next(); + // i.remove(); + // } + } + + + QList Logger::appenders() const + { + QReadLocker locker(&mObjectGuard); + + QList result; + Appender *p_appender; + Q_FOREACH(p_appender, mAppenders) + result << p_appender; + return result; + } + + + void Logger::setLevel(Level level) + { + // QWriteLocker locker(&mObjectGuard); // Read/Write int is safe + + if ((parentLogger() == 0) && (level == Level::NULL_INT)) + { + logger()->warn("Invalid root logger level NULL_INT. Using DEBUG_INT instead"); + level = Level::DEBUG_INT; + } + mLevel = level; + } + + + void Logger::addAppender(Appender *pAppender) + { + // Avoid deadlock: + // - Handle warnings, before write lock is aquired + + // Keep objects with a 0 reference count safe + LogObjectPtr p_appender = pAppender; + + { + QReadLocker locker(&mObjectGuard); + + if(!p_appender) + { + logger()->warn("Adding null Appender to Logger '%1'", name()); + return; + } + if(mAppenders.contains(p_appender)) + { + logger()->warn("Adding of duplicate appender '%2' to logger '%1'", name(), p_appender->name()); + return; + } + } + { + QWriteLocker locker(&mObjectGuard); + + if(mAppenders.contains(p_appender)) + return; + mAppenders.append(p_appender); + } + } + + + Appender *Logger::appender(const QString &rName) const + { + QReadLocker locker(&mObjectGuard); + + Appender *p_appender; + Q_FOREACH(p_appender, mAppenders) + if (p_appender->name() == rName) + return p_appender; + return 0; + } + + + + void Logger::callAppenders(const LoggingEvent &rEvent) const + { + QReadLocker locker(&mObjectGuard); + + Appender *p_appender; + Q_FOREACH(p_appender, mAppenders) + p_appender->doAppend(rEvent); + if (additivity() && (parentLogger() != 0)) + parentLogger()->callAppenders(rEvent); + } + + + bool Logger::isAttached(Appender *pAppender) const + { + QReadLocker locker(&mObjectGuard); + + // Keep objects with a 0 reference count safe + LogObjectPtr p_appender = pAppender; + + return mAppenders.contains(p_appender); + } + + + void Logger::removeAllAppenders() + { + // Avoid deadlock: + // - Only log warnings without having the write log aquired + // - Hold a reference to all appenders so that the remove does not + // destruct the appender over the reference count while the write + // log is held. The appender may log messages. + + logger()->trace("Removing all appenders from logger '%1'", name()); + + QList< LogObjectPtr > appenders; + { + QWriteLocker locker(&mObjectGuard); + QMutableListIterator< LogObjectPtr > i(mAppenders); + while (i.hasNext()) + { + Appender *p_appender = i.next(); + ListAppender *p_listappender = qobject_cast(p_appender); + if (p_listappender && p_listappender->configuratorList()) + continue; + else + { + appenders << p_appender; + i.remove(); + } + } + } + appenders.clear(); + } + + + void Logger::removeAppender(Appender *pAppender) + { + // Avoid deadlock: + // - Only log warnings without having the write log aquired + // - Hold a reference to the appender so that the remove does not + // destruct the appender over the reference count while the write + // log is held. The appender may log messages. + + LogObjectPtr p_appender = pAppender; + + if(!p_appender) + { + logger()->warn("Request to remove null Appender from Logger '%1'", name()); + return; + } + int n; + { + QWriteLocker locker(&mObjectGuard); + + n = mAppenders.removeAll(p_appender); + } + if (n == 0) + { + logger()->warn("Request to remove Appender '%2', which is not part of Logger '%1' appenders", name(), p_appender->name()); + return; + } + } + + + void Logger::removeAppender(const QString &rName) + { + Appender *p_appender = appender(rName); + if (p_appender) + removeAppender(p_appender); + } + + + Level Logger::effectiveLevel() const + { + Q_ASSERT_X(LogManager::rootLogger()->level() != Level::NULL_INT, "Logger::effectiveLevel()", "Root logger level must not be NULL_INT"); + + QReadLocker locker(&mObjectGuard); + + const Logger *p_logger = this; + while (p_logger->level() == Level::NULL_INT) + p_logger = p_logger->parentLogger(); + return p_logger->level(); + } + + + bool Logger::isEnabledFor(Level level) const + { + if (mpLoggerRepository->isDisabled(level)) + return false; + return (effectiveLevel() <= level); + } + + + Logger *Logger::logger(const QString &rName) + { + return LogManager::logger(rName); + } + + + Logger *Logger::logger(const char *pName) + { + return LogManager::logger(QLatin1String(pName)); + } + + + Logger *Logger::rootLogger() + { + return LogManager::rootLogger(); + } + + +#ifndef QT_NO_DEBUG_STREAM + QDebug Logger::debug(QDebug &rDebug) const + { + QReadLocker locker(&mObjectGuard); + + QString parent_logger; + if (mpParent) + parent_logger = mpParent->name(); + + rDebug.nospace() << "Logger(" + << "name:" << name() << " " + << "appenders:" << mAppenders.count() << " " + << "additivity:" << mAdditivity << " " + << mLevel + << "parentLogger:" << parent_logger + << ")"; + return rDebug.space(); + } +#endif // QT_NO_DEBUG_STREAM + + + void Logger::forcedLog(Level level, const QString &rMessage) const + { + QReadLocker locker(&mObjectGuard); + + LoggingEvent event(this, level, rMessage); + callAppenders(event); + } + + + + /************************************************************************** + * Implementation: Operators, Helper + **************************************************************************/ + + +#ifndef QT_NO_DEBUG_STREAM + QDebug operator<<(QDebug debug, const Logger &rLogger) + { + return rLogger.debug(debug); + } +#endif // QT_NO_DEBUG_STREAM + + + +} // namespace Log4Qt diff --git a/src/log4qt/src/log4qt/logger.h b/src/log4qt/src/log4qt/logger.h new file mode 100644 index 0000000..1b58adc --- /dev/null +++ b/src/log4qt/src/log4qt/logger.h @@ -0,0 +1,1665 @@ +/****************************************************************************** + * + * package: Log4Qt + * file: logger.h + * created: September 2007 + * author: Martin Heinrich + * + * + * changes: Sep 2008, Martin Heinrich: + * - Replaced usage of q_atomic_test_and_set_ptr with + * QBasicAtomicPointer + * + * + * Copyright 2007 - 2008 Martin Heinrich + * + * 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. + * + ******************************************************************************/ + +#ifndef LOG4QT_LOGGER_H +#define LOG4QT_LOGGER_H + + +/****************************************************************************** + * Dependencies + ******************************************************************************/ + +#include + +#include +#include +#include +#include "log4qt/helpers/logerror.h" +#include "log4qt/helpers/classlogger.h" +#include "log4qt/helpers/logobjectptr.h" +#include "log4qt/level.h" + +#if QT_VERSION >= QT_VERSION_CHECK(4, 4, 0) +# ifndef Q_ATOMIC_POINTER_TEST_AND_SET_IS_ALWAYS_NATIVE +# warning "QAtomicPointer test and set is not native. The macro Log4Qt::LOG4QT_DECLARE_STATIC_LOGGER is not thread-safe." +# endif +#endif + + +/****************************************************************************** + * Declarations + ******************************************************************************/ + +namespace Log4Qt +{ + + /*! + * LOG4QT_DECLARE_STATIC_LOGGER declares a static function \a FUNCTION that + * returns a pointer to a \ref Log4Qt::Logger "Logger" named after \a CLASS. + * + * On the first invocation the \ref Log4Qt::Logger "Logger" is requested + * by calling \ref Log4Qt::Logger::logger(const char *pName) + * "Logger::logger( #CLASS )". The pointer is stored to be returned on + * subsequent invocations. + * + * The following example shows how to use the macro to define a logger to be + * used within a class not derived from QObject. + * + * \code + * #file: counter.h + * + * #include logger.h + * + * class Counter + * { + * public: + * Counter(); + * Counter(int preset); + * private: + * int mCount; + * } + * \endcode + * \code + * #file: counter.cpp + * + * #include counter.h + * + * LOG4QT_DECLARE_STATIC_LOGGER(logger, Counter) + * + * Counter::Counter() : + * mCount(0) + * {} + * + * void Counter::Counter(int preset) : + * mCount(preset) + * { + * if (preset < 0) + * { + * logger()->warn("Invalid negative counter preset %1. Using 0 instead.", preset); + * mCount = 0; + * } + * } + * \endcode + * + * \note The function created by the macro is thread-safe. + * + * \sa \ref Log4Qt::Logger::logger(const char *pName) "Logger::logger(const char *pName)" + */ +#if QT_VERSION < QT_VERSION_CHECK(4, 4, 0) + #define LOG4QT_DECLARE_STATIC_LOGGER(FUNCTION, CLASS) \ + static Log4Qt::Logger *FUNCTION() \ + { \ + static Log4Qt::Logger *p_logger = 0; \ + if (!p_logger) \ + { \ + q_atomic_test_and_set_ptr( \ + &p_logger, \ + 0, \ + Log4Qt::Logger::logger( #CLASS )); \ + } \ + return p_logger; \ + } +#elif QT_VERSION < QT_VERSION_CHECK(5, 0, 0) + #define LOG4QT_DECLARE_STATIC_LOGGER(FUNCTION, CLASS) \ + static Log4Qt::Logger *FUNCTION() \ + { \ + static QBasicAtomicPointer p_logger = \ + Q_BASIC_ATOMIC_INITIALIZER(0); \ + if (!p_logger) \ + { \ + p_logger.testAndSetOrdered(0, \ + Log4Qt::Logger::logger( #CLASS )); \ + } \ + return p_logger; \ + } +#else + #define LOG4QT_DECLARE_STATIC_LOGGER(FUNCTION, CLASS) \ + static Log4Qt::Logger *FUNCTION() \ + { \ + static QBasicAtomicPointer p_logger = \ + Q_BASIC_ATOMIC_INITIALIZER(0); \ + if (!p_logger.loadAcquire()) \ + { \ + p_logger.testAndSetOrdered(0, \ + Log4Qt::Logger::logger( #CLASS )); \ + } \ + return p_logger.loadAcquire(); \ + } +#endif + + /*! + * LOG4QT_DECLARE_QCLASS_LOGGER declares member functions to retrieve + * \ref Log4Qt::Logger "Logger" for the class it is used in. + * + * On the first invocation the \ref Log4Qt::Logger "Logger" is requested + * by a call to \ref Log4Qt::Logger::logger(const char *pName) + * "Logger::logger(const char *pName)". The pointer is stored to be + * returned on subsequent invocations. + * + * The following example shows how to use the macro to define a logger to be + * used within a class derived from QObject. + * + * \code + * #file: counter.h + * + * #include qobject.h + * #include logger.h + * + * class Counter : public QObject + * { + * Q_OBJECT + * LOG4QT_DECLARE_QCLASS_LOGGER + * public: + * Counter(); + * Counter(int preset); + * private: + * int mCount; + * } + * \endcode + * \code + * #file: counter.cpp + * + * #include counter.h + * + * Counter::Counter() : + * mCount(0) + * {} + * + * void Counter::Counter(int preset) + * mCount(preset) + * { + * if (preset < 0) + * { + * logger()->warn("Invalid negative counter preset %1. Using 0 instead.", preset); + * mCount = 0; + * } + * } + * \endcode + * + * \note The function created by the macro is thread-safe. + * + * \sa \ref Log4Qt::Logger::logger(const char *pName) "Logger::logger(const char *pName)", + * \ref Log4Qt::ClassLogger "ClassLogger" + */ + #define LOG4QT_DECLARE_QCLASS_LOGGER \ + private: \ + mutable Log4Qt::ClassLogger mLog4QtClassLogger; \ + public: \ + inline Log4Qt::Logger *logger() const \ + { return mLog4QtClassLogger.logger(this); } \ + private: + + class Appender; + class LoggingEvent; + class LoggerRepository; + + /*! + * \brief The class Logger provides logging services. + * + * A pointer to a logger can be retrieved by calling Logger::logger() or + * LogManager::logger() with the class name as argument. Because a logger + * is never destroyed it is possible to store the pointer to the logger. + * This way the lookup of the pointer in the repository is only required + * on the first logging operation. The macros \ref + * Log4Qt::LOG4QT_DECLARE_STATIC_LOGGER "LOG4QT_DECLARE_STATIC_LOGGER" and + * \ref Log4Qt::LOG4QT_DECLARE_QCLASS_LOGGER "LOG4QT_DECLARE_QCLASS_LOGGER" + * provide a thread-safe implementation to store the logger pointer. + * + * \note All the functions declared in this class are thread-safe. + */ + class Logger : public QObject + { + Q_OBJECT + + /*! + * The property holds, if the logger is additive. + * + * The default is true for being additive. + * + * \sa additive(), setAdditive() + */ + Q_PROPERTY(bool additivity READ additivity WRITE setAdditivity) + + /*! + * The property holds the level used by the logger. + * + * The default is Level::NULL_INT. + * \sa level(), setLevel() + */ + Q_PROPERTY(Level level READ level WRITE setLevel) + + /*! + * The property holds the LoggerRepository of the logger. + * + * \sa loggerRepository() + */ + Q_PROPERTY(LoggerRepository* loggerRepository READ loggerRepository) + + /*! + * The property holds the name of the logger. + * + * \sa name() + */ + Q_PROPERTY(QString name READ name) + + /*! + * The property holds the parent logger of the logger. + * + * \sa parentLogger() + */ + Q_PROPERTY(Logger* parentLogger READ parentLogger) + + LOG4QT_DECLARE_QCLASS_LOGGER + + protected: + Logger(LoggerRepository* pLoggerRepository, Level level, const QString &rName, Logger *pParent = 0); + virtual ~Logger(); + private: + Logger(const Logger &rOther); // Not implemented + Logger &operator=(const Logger &rOther); // Not implemented + + public: + bool additivity() const; + QList appenders() const; + Level level() const; + LoggerRepository *loggerRepository() const; + QString name() const; + Logger *parentLogger() const; + // JAVA: ResourceBundle *resourceBundle() const; + // JAVA: void setResourceBundle(ResourceBundle *pResourceBundle); + void setAdditivity(bool additivity); + virtual void setLevel(Level level); + + void addAppender(Appender *pAppender); + Appender *appender(const QString &rName) const; + void callAppenders(const LoggingEvent &rEvent) const; + bool isAttached(Appender *pAppender) const; + + /*! + * Removes all appenders that have been previously added from this + * Logger. + * + * To allow configurators to collect events during the configuration + * process ListAppenders with the configuratorList property set, will + * not be removed. + * + * \sa LisAppender::setConfiguratorList() + */ + void removeAllAppenders(); + + void removeAppender(Appender *pAppender); + void removeAppender(const QString &rName); + // JAVA: QString resourceBundleString(const QString &rKey) const; + + Level effectiveLevel() const; + bool isDebugEnabled() const; + + /*! + * Checks if this logger is enabled for a given Level \a level. If the + * logger is enabled the function returns true. Otherwise it returns + * false. + * + * A logger is enabled for a level, if the level is greater or equal + * then the repository threshold and greater and equal then the loggers + * effective level. + * + * \sa LoggerRepository::isDisabled(), effectiveLevel() + */ + bool isEnabledFor(Level level) const; + + bool isErrorEnabled() const; + bool isFatalEnabled() const; + bool isInfoEnabled() const; + bool isTraceEnabled() const; + bool isWarnEnabled() const; + + void debug(const QString &rMessage) const; + void debug(const LogError &rLogError) const; + void debug(const char *pMessage) const; + void debug(const char *pMessage, + const QString &rArg1) const; + void debug(const char *pMessage, + int arg1) const; + void debug(const char *pMessage, + const QString &rArg1, + const QString &rArg2) const; + void debug(const char *pMessage, + const QString &rArg1, + int arg2) const; + void debug(const char *pMessage, + int arg1, + const QString &rArg2) const; + void debug(const char *pMessage, + int arg1, + int arg2) const; + void debug(const char *pMessage, + const QString &rArg1, + const QString &rArg2, + const QString &rArg3) const; + void debug(const char *pMessage, + const QString &rArg1, + const QString &rArg2, + int arg3) const; + void debug(const char *pMessage, + const QString &rArg1, + int arg2, + const QString &rArg3) const; + void debug(const char *pMessage, + const QString &rArg1, + int arg2, + int arg3) const; + void debug(const char *pMessage, + int arg1, + const QString &rArg2, + const QString &rArg3) const; + void debug(const char *pMessage, + int arg1, + const QString &rArg2, + int arg3) const; + void debug(const char *pMessage, + int arg1, + int arg2, + const QString &rArg3) const; + void debug(const char *pMessage, + int arg1, + int arg2, + int arg3) const; + void debug(const char *pMessage, + const QVariant &rArg1, + const QVariant &rArg2, + const QVariant &rArg3) const; + + void error(const QString &rMessage) const; + void error(const LogError &rLogError) const; + void error(const char *pMessage) const; + void error(const char *pMessage, + const QString &rArg1) const; + void error(const char *pMessage, + int arg1) const; + void error(const char *pMessage, + const QString &rArg1, + const QString &rArg2) const; + void error(const char *pMessage, + const QString &rArg1, int arg2) const; + void error(const char *pMessage, + int arg1, + const QString &rArg2) const; + void error(const char *pMessage, + int arg1, + int arg2) const; + void error(const char *pMessage, + const QString &rArg1, + const QString &rArg2, + const QString &rArg3) const; + void error(const char *pMessage, + const QString &rArg1, + const QString &rArg2, + int arg3) const; + void error(const char *pMessage, + const QString &rArg1, + int arg2, + const QString &rArg3) const; + void error(const char *pMessage, + const QString &rArg1, + int arg2, + int arg3) const; + void error(const char *pMessage, + int arg1, + const QString &rArg2, + const QString &rArg3) const; + void error(const char *pMessage, + int arg1, + const QString &rArg2, + int arg3) const; + void error(const char *pMessage, + int arg1, + int arg2, + const QString &rArg3) const; + void error(const char *pMessage, + int arg1, + int arg2, + int arg3) const; + void error(const char *pMessage, + const QVariant &rArg1, + const QVariant &rArg2, + const QVariant &rArg3) const; + + void fatal(const QString &rMessage) const; + void fatal(const LogError &rLogError) const; + void fatal(const char *pMessage) const; + void fatal(const char *pMessage, + const QString &rArg1) const; + void fatal(const char *pMessage, + int arg1) const; + void fatal(const char *pMessage, + const QString &rArg1, + const QString &rArg2) const; + void fatal(const char *pMessage, + const QString &rArg1, + int arg2) const; + void fatal(const char *pMessage, + int arg1, + const QString &rArg2) const; + void fatal(const char *pMessage, + int arg1, + int arg2) const; + void fatal(const char *pMessage, + const QString &rArg1, + const QString &rArg2, + const QString &rArg3) const; + void fatal(const char *pMessage, + const QString &rArg1, + const QString &rArg2, + int arg3) const; + void fatal(const char *pMessage, + const QString &rArg1, + int arg2, + const QString &rArg3) const; + void fatal(const char *pMessage, + const QString &rArg1, + int arg2, + int arg3) const; + void fatal(const char *pMessage, + int arg1, + const QString &rArg2, + const QString &rArg3) const; + void fatal(const char *pMessage, + int arg1, + const QString &rArg2, + int arg3) const; + void fatal(const char *pMessage, + int arg1, + int arg2, + const QString &rArg3) const; + void fatal(const char *pMessage, + int arg1, + int arg2, + int arg3) const; + void fatal(const char *pMessage, + const QVariant &rArg1, + const QVariant &rArg2, + const QVariant &rArg3) const; + + void info(const QString &rMessage) const; + void info(const LogError &rLogError) const; + void info(const char *pMessage) const; + void info(const char *pMessage, + const QString &rArg1) const; + void info(const char *pMessage, + int arg1) const; + void info(const char *pMessage, + const QString &rArg1, + const QString &rArg2) const; + void info(const char *pMessage, + const QString &rArg1, + int arg2) const; + void info(const char *pMessage, + int arg1, + const QString &rArg2) const; + void info(const char *pMessage, + int arg1, + int arg2) const; + void info(const char *pMessage, + const QString &rArg1, + const QString &rArg2, + const QString &rArg3) const; + void info(const char *pMessage, + const QString &rArg1, + const QString &rArg2, + int arg3) const; + void info(const char *pMessage, + const QString &rArg1, + int arg2, + const QString &rArg3) const; + void info(const char *pMessage, + const QString &rArg1, + int arg2, + int arg3) const; + void info(const char *pMessage, + int arg1, + const QString &rArg2, + const QString &rArg3) const; + void info(const char *pMessage, + int arg1, + const QString &rArg2, + int arg3) const; + void info(const char *pMessage, + int arg1, + int arg2, + const QString &rArg3) const; + void info(const char *pMessage, + int arg1, + int arg2, + int arg3) const; + void info(const char *pMessage, + const QVariant &rArg1, + const QVariant &rArg2, + const QVariant &rArg3) const; + + void log(Level level, + const QString &rMessage) const; + void log(Level level, + const LogError &rLogError) const; + void log(Level level, + const char *pMessage) const; + void log(Level level, + const char *pMessage, + const QString &rArg1) const; + void log(Level level, + const char *pMessage, + int arg1) const; + void log(Level level, + const char *pMessage, + const QString &rArg1, + const QString &rArg2) const; + void log(Level level, + const char *pMessage, + const QString &rArg1, + int arg2) const; + void log(Level level, + const char *pMessage, + int arg1, + const QString &rArg2) const; + void log(Level level, + const char *pMessage, + int arg1, + int arg2) const; + void log(Level level, + const char *pMessage, + const QString &rArg1, + const QString &rArg2, + const QString &rArg3) const; + void log(Level level, + const char *pMessage, + const QString &rArg1, + const QString &rArg2, + int arg3) const; + void log(Level level, + const char *pMessage, + const QString &rArg1, + int arg2, + const QString &rArg3) const; + void log(Level level, + const char *pMessage, + const QString &rArg1, + int arg2, + int arg3) const; + void log(Level level, + const char *pMessage, + int arg1, + const QString &rArg2, + const QString &rArg3) const; + void log(Level level, + const char *pMessage, + int arg1, + const QString &rArg2, + int arg3) const; + void log(Level level, + const char *pMessage, + int arg1, + int arg2, + const QString &rArg3) const; + void log(Level level, + const char *pMessage, + int arg1, + int arg2, + int arg3) const; + void log(Level level, + const char *pMessage, + const QVariant &rArg1, + const QVariant &rArg2, + const QVariant &rArg3) const; + + // JAVA: void l7dlog(Level level, + // const QString &rKey); + // JAVA: void l7dlog(Level level, + // const QString &rKey, + // const QList rParameters); + + void trace(const QString &rMessage) const; + void trace(const LogError &rLogError) const; + void trace(const char *pMessage) const; + void trace(const char *pMessage, + const QString &rArg1) const; + void trace(const char *pMessage, + int arg1) const; + void trace(const char *pMessage, + const QString &rArg1, + const QString &rArg2) const; + void trace(const char *pMessage, + const QString &rArg1, + int arg2) const; + void trace(const char *pMessage, + int arg1, + const QString &rArg2) const; + void trace(const char *pMessage, + int arg1, + int arg2) const; + void trace(const char *pMessage, + const QString &rArg1, + const QString &rArg2, + const QString &rArg3) const; + void trace(const char *pMessage, + const QString &rArg1, + const QString &rArg2, + int arg3) const; + void trace(const char *pMessage, + const QString &rArg1, + int arg2, + const QString &rArg3) const; + void trace(const char *pMessage, + const QString &rArg1, + int arg2, + int arg3) const; + void trace(const char *pMessage, + int arg1, + const QString &rArg2, + const QString &rArg3) const; + void trace(const char *pMessage, + int arg1, + const QString &rArg2, + int arg3) const; + void trace(const char *pMessage, + int arg1, + int arg2, + const QString &rArg3) const; + void trace(const char *pMessage, + int arg1, + int arg2, + int arg3) const; + void trace(const char *pMessage, + const QVariant &rArg1, + const QVariant &rArg2, + const QVariant &rArg3) const; + + void warn(const QString &rMessage) const; + void warn(const LogError &rLogError) const; + void warn(const char *pMessage) const; + void warn(const char *pMessage, + const QString &rArg1) const; + void warn(const char *pMessage, + int arg1) const; + void warn(const char *pMessage, + const QString &rArg1, + const QString &rArg2) const; + void warn(const char *pMessage, + const QString &rArg1, + int arg2) const; + void warn(const char *pMessage, + int arg1, + const QString &rArg2) const; + void warn(const char *pMessage, + int arg1, + int arg2) const; + void warn(const char *pMessage, + const QString &rArg1, + const QString &rArg2, + const QString &rArg3) const; + void warn(const char *pMessage, + const QString &rArg1, + const QString &rArg2, + int arg3) const; + void warn(const char *pMessage, + const QString &rArg1, + int arg2, + const QString &rArg3) const; + void warn(const char *pMessage, + const QString &rArg1, + int arg2, + int arg3) const; + void warn(const char *pMessage, + int arg1, + const QString &rArg2, + const QString &rArg3) const; + void warn(const char *pMessage, + int arg1, + const QString &rArg2, + int arg3) const; + void warn(const char *pMessage, + int arg1, + int arg2, + const QString &rArg3) const; + void warn(const char *pMessage, + int arg1, + int arg2, + int arg3) const; + void warn(const char *pMessage, + const QVariant &rArg1, + const QVariant &rArg2, + const QVariant &rArg3) const; + + // LogManager operations + static Logger *logger(const QString &rName); + static Logger *logger(const char *pName); + static Logger *rootLogger(); + + protected: +#ifndef QT_NO_DEBUG_STREAM + /*! + * Writes all object member variables to the given debug stream \a rDebug + * and returns the stream. + * + * + * %Logger(name:"Log4Qt" appenders:0 additivity:true Level("NULL") + * parentLogger: "root" ) + * + * \sa QDebug, operator<<(QDebug debug, const Appender &rAppender) + */ + virtual QDebug debug(QDebug &rDebug) const; + friend QDebug operator<<(QDebug debug, + const Logger &rLogger); +#endif // QT_NO_DEBUG_STREAM + + void forcedLog(Level level, + const QString &rMessage) const; + + protected: + mutable QReadWriteLock mObjectGuard; + private: + const QString mName; + LoggerRepository* mpLoggerRepository; + volatile bool mAdditivity; + QList< LogObjectPtr > mAppenders; + Level mLevel; + Logger *mpParent; + + // Needs to be friend to create Logger objects + friend class Hierarchy; + }; + + + /****************************************************************************** + * Operators, Helper + ******************************************************************************/ + +#ifndef QT_NO_DEBUG_STREAM + /*! + * \relates Logger + * + * Writes all object member variables to the given debug stream \a debug and + * returns the stream. + * + * To handle subclassing the function uses the virtual member function debug(). + * This allows each class to generate its own output. + * + * \sa QDebug, debug() + */ + QDebug operator<<(QDebug debug, + const Logger &rLogger); +#endif // QT_NO_DEBUG_STREAM + + + /************************************************************************** + * Inline + **************************************************************************/ + + inline bool Logger::additivity() const + { // QReadLocker locker(&mObjectGuard); // Read/Write of int is safe + return mAdditivity; } + + inline Level Logger::level() const + { // QReadLocker locker(&mObjectGuard); // Level is thread-safe + return mLevel; } + + inline LoggerRepository *Logger::loggerRepository() const + { // QReadLocker locker(&mObjectGuard); // Constant for object lifetime + return mpLoggerRepository; } + + inline QString Logger::name() const + { // QReadLocker locker(&mObjectGuard); // Constant for object lifetime + return mName; } + + inline Logger *Logger::parentLogger() const + { // QReadLocker locker(&mObjectGuard); // Constant for object lifetime + return mpParent; } + + inline void Logger::setAdditivity(bool additivity) + { // QWriteLocker locker(&mObjectGuard); // Read/Write of int is safe + mAdditivity = additivity; } + + // Level operations + + inline bool Logger::isDebugEnabled() const + { return isEnabledFor(Level::DEBUG_INT); } + + inline bool Logger::isErrorEnabled() const + { return isEnabledFor(Level::ERROR_INT); } + + inline bool Logger::isFatalEnabled() const + { return isEnabledFor(Level::FATAL_INT); } + + inline bool Logger::isInfoEnabled() const + { return isEnabledFor(Level::INFO_INT); } + + inline bool Logger::isTraceEnabled() const + { return isEnabledFor(Level::TRACE_INT); } + + inline bool Logger::isWarnEnabled() const + { return isEnabledFor(Level::WARN_INT); } + + // Log operations: debug + + inline void Logger::debug(const LogError &rLogError) const + { if (isEnabledFor(Level::DEBUG_INT)) + forcedLog(Level::DEBUG_INT, rLogError.toString()); } + + inline void Logger::debug(const QString &rMessage) const + { if (isEnabledFor(Level::DEBUG_INT)) + forcedLog(Level::DEBUG_INT, rMessage); } + + inline void Logger::debug(const char *pMessage) const + { if (isEnabledFor(Level::DEBUG_INT)) + forcedLog(Level::DEBUG_INT, QString::fromUtf8(pMessage)); } + + inline void Logger::debug(const char *pMessage, + const QString &rArg1) const + { if (isEnabledFor(Level::DEBUG_INT)) + forcedLog(Level::DEBUG_INT, QString::fromUtf8(pMessage).arg(rArg1)); } + + inline void Logger::debug(const char *pMessage, + int arg1) const + { if (isEnabledFor(Level::DEBUG_INT)) + forcedLog(Level::DEBUG_INT, QString::fromUtf8(pMessage).arg(arg1)); } + + inline void Logger::debug(const char *pMessage, + const QString &rArg1, + const QString &rArg2) const + { if (isEnabledFor(Level::DEBUG_INT)) + forcedLog(Level::DEBUG_INT, QString::fromUtf8(pMessage).arg(rArg1, rArg2)); } + + inline void Logger::debug(const char *pMessage, + const QString &rArg1, + int arg2) const + { if (isEnabledFor(Level::DEBUG_INT)) + forcedLog(Level::DEBUG_INT, QString::fromUtf8(pMessage).arg(rArg1).arg(arg2)); } + + inline void Logger::debug(const char *pMessage, + int arg1, + const QString &rArg2) const + { if (isEnabledFor(Level::DEBUG_INT)) + forcedLog(Level::DEBUG_INT, QString::fromUtf8(pMessage).arg(arg1).arg(rArg2)); } + + inline void Logger::debug(const char *pMessage, + int arg1, + int arg2) const + { if (isEnabledFor(Level::DEBUG_INT)) + forcedLog(Level::DEBUG_INT, QString::fromUtf8(pMessage).arg(arg1).arg(arg2)); } + + inline void Logger::debug(const char *pMessage, + const QString &rArg1, + const QString &rArg2, + const QString &rArg3) const + { if (isEnabledFor(Level::DEBUG_INT)) + forcedLog(Level::DEBUG_INT, QString::fromUtf8(pMessage).arg(rArg1, rArg2, rArg3)); } + + inline void Logger::debug(const char *pMessage, + const QString &rArg1, + const QString &rArg2, + int arg3) const + { if (isEnabledFor(Level::DEBUG_INT)) + forcedLog(Level::DEBUG_INT, QString::fromUtf8(pMessage).arg(rArg1, rArg2).arg(arg3)); } + + inline void Logger::debug(const char *pMessage, + const QString &rArg1, + int arg2, + const QString &rArg3) const + { if (isEnabledFor(Level::DEBUG_INT)) + forcedLog(Level::DEBUG_INT, QString::fromUtf8(pMessage).arg(rArg1).arg(arg2).arg(rArg3)); } + + inline void Logger::debug(const char *pMessage, + const QString &rArg1, + int arg2, + int arg3) const + { if (isEnabledFor(Level::DEBUG_INT)) + forcedLog(Level::DEBUG_INT, QString::fromUtf8(pMessage).arg(rArg1).arg(arg2).arg(arg3)); } + + inline void Logger::debug(const char *pMessage, + int arg1, + const QString &rArg2, + const QString &rArg3) const + { if (isEnabledFor(Level::DEBUG_INT)) + forcedLog(Level::DEBUG_INT, QString::fromUtf8(pMessage).arg(arg1).arg(rArg2).arg(rArg3)); } + + inline void Logger::debug(const char *pMessage, + int arg1, + const QString &rArg2, + int arg3) const + { if (isEnabledFor(Level::DEBUG_INT)) + forcedLog(Level::DEBUG_INT, QString::fromUtf8(pMessage).arg(arg1).arg(rArg2).arg(arg3)); } + + inline void Logger::debug(const char *pMessage, + int arg1, + int arg2, + const QString &rArg3) const + { if (isEnabledFor(Level::DEBUG_INT)) + forcedLog(Level::DEBUG_INT, QString::fromUtf8(pMessage).arg(arg1).arg(arg2).arg(rArg3)); } + + inline void Logger::debug(const char *pMessage, + int arg1, + int arg2, + int arg3) const + { if (isEnabledFor(Level::DEBUG_INT)) + forcedLog(Level::DEBUG_INT, QString::fromUtf8(pMessage).arg(arg1).arg(arg2).arg(arg3)); } + + inline void Logger::debug(const char *pMessage, + const QVariant &rArg1, + const QVariant &rArg2, + const QVariant &rArg3) const + { if (isEnabledFor(Level::DEBUG_INT)) + forcedLog(Level::DEBUG_INT, QString::fromUtf8(pMessage).arg(rArg1.toString(), rArg2.toString(), rArg3.toString())); } + + // Log operations: error + + inline void Logger::error(const QString &rMessage) const + { if (isEnabledFor(Level::ERROR_INT)) + forcedLog(Level::ERROR_INT, rMessage); } + + inline void Logger::error(const LogError &rLogError) const + { if (isEnabledFor(Level::ERROR_INT)) + forcedLog(Level::ERROR_INT, rLogError.toString()); } + + inline void Logger::error(const char *pMessage) const + { if (isEnabledFor(Level::ERROR_INT)) + forcedLog(Level::ERROR_INT, QString::fromUtf8(pMessage)); } + + inline void Logger::error(const char *pMessage, + const QString &rArg1) const + { if (isEnabledFor(Level::ERROR_INT)) + forcedLog(Level::ERROR_INT, QString::fromUtf8(pMessage).arg(rArg1)); } + + inline void Logger::error(const char *pMessage, + int arg1) const + { if (isEnabledFor(Level::ERROR_INT)) + forcedLog(Level::ERROR_INT, QString::fromUtf8(pMessage).arg(arg1)); } + + inline void Logger::error(const char *pMessage, + const QString &rArg1, + const QString &rArg2) const + { if (isEnabledFor(Level::ERROR_INT)) + forcedLog(Level::ERROR_INT, QString::fromUtf8(pMessage).arg(rArg1, rArg2)); } + + inline void Logger::error(const char *pMessage, + const QString &rArg1, + int arg2) const + { if (isEnabledFor(Level::ERROR_INT)) + forcedLog(Level::ERROR_INT, QString::fromUtf8(pMessage).arg(rArg1).arg(arg2)); } + + inline void Logger::error(const char *pMessage, + int arg1, + const QString &rArg2) const + { if (isEnabledFor(Level::ERROR_INT)) + forcedLog(Level::ERROR_INT, QString::fromUtf8(pMessage).arg(arg1).arg(rArg2)); } + + inline void Logger::error(const char *pMessage, + int arg1, + int arg2) const + { if (isEnabledFor(Level::ERROR_INT)) + forcedLog(Level::ERROR_INT, QString::fromUtf8(pMessage).arg(arg1).arg(arg2)); } + + inline void Logger::error(const char *pMessage, + const QString &rArg1, + const QString &rArg2, + const QString &rArg3) const + { if (isEnabledFor(Level::ERROR_INT)) + forcedLog(Level::ERROR_INT, QString::fromUtf8(pMessage).arg(rArg1, rArg2, rArg3)); } + + inline void Logger::error(const char *pMessage, + const QString &rArg1, + const QString &rArg2, + int arg3) const + { if (isEnabledFor(Level::ERROR_INT)) + forcedLog(Level::ERROR_INT, QString::fromUtf8(pMessage).arg(rArg1, rArg2).arg(arg3)); } + + inline void Logger::error(const char *pMessage, + const QString &rArg1, + int arg2, + const QString &rArg3) const + { if (isEnabledFor(Level::ERROR_INT)) + forcedLog(Level::ERROR_INT, QString::fromUtf8(pMessage).arg(rArg1).arg(arg2).arg(rArg3)); } + + inline void Logger::error(const char *pMessage, + const QString &rArg1, + int arg2, + int arg3) const + { if (isEnabledFor(Level::ERROR_INT)) + forcedLog(Level::ERROR_INT, QString::fromUtf8(pMessage).arg(rArg1).arg(arg2).arg(arg3)); } + + inline void Logger::error(const char *pMessage, + int arg1, + const QString &rArg2, + const QString &rArg3) const + { if (isEnabledFor(Level::ERROR_INT)) + forcedLog(Level::ERROR_INT, QString::fromUtf8(pMessage).arg(arg1).arg(rArg2).arg(rArg3)); } + + inline void Logger::error(const char *pMessage, + int arg1, + const QString &rArg2, + int arg3) const + { if (isEnabledFor(Level::ERROR_INT)) + forcedLog(Level::ERROR_INT, QString::fromUtf8(pMessage).arg(arg1).arg(rArg2).arg(arg3)); } + + inline void Logger::error(const char *pMessage, + int arg1, + int arg2, + const QString &rArg3) const + { if (isEnabledFor(Level::ERROR_INT)) + forcedLog(Level::ERROR_INT, QString::fromUtf8(pMessage).arg(arg1).arg(arg2).arg(rArg3)); } + + inline void Logger::error(const char *pMessage, + int arg1, + int arg2, + int arg3) const + { if (isEnabledFor(Level::ERROR_INT)) + forcedLog(Level::ERROR_INT, QString::fromUtf8(pMessage).arg(arg1).arg(arg2).arg(arg3)); } + + inline void Logger::error(const char *pMessage, + const QVariant &rArg1, + const QVariant &rArg2, + const QVariant &rArg3) const + { if (isEnabledFor(Level::ERROR_INT)) + forcedLog(Level::ERROR_INT, QString::fromUtf8(pMessage).arg(rArg1.toString(), rArg2.toString(), rArg3.toString())); } + + // Log operations: fatal + + inline void Logger::fatal(const QString &rMessage) const + { if (isEnabledFor(Level::FATAL_INT)) + forcedLog(Level::FATAL_INT, rMessage); } + + inline void Logger::fatal(const LogError &rLogError) const + { if (isEnabledFor(Level::FATAL_INT)) + forcedLog(Level::FATAL_INT, rLogError.toString()); } + + inline void Logger::fatal(const char *pMessage) const + { if (isEnabledFor(Level::FATAL_INT)) + forcedLog(Level::FATAL_INT, QString::fromUtf8(pMessage)); } + + inline void Logger::fatal(const char *pMessage, + const QString &rArg1) const + { if (isEnabledFor(Level::FATAL_INT)) + forcedLog(Level::FATAL_INT, QString::fromUtf8(pMessage).arg(rArg1)); } + + inline void Logger::fatal(const char *pMessage, + int arg1) const + { if (isEnabledFor(Level::FATAL_INT)) + forcedLog(Level::FATAL_INT, QString::fromUtf8(pMessage).arg(arg1)); } + + inline void Logger::fatal(const char *pMessage, + const QString &rArg1, const QString &rArg2) const + { if (isEnabledFor(Level::FATAL_INT)) + forcedLog(Level::FATAL_INT, QString::fromUtf8(pMessage).arg(rArg1, rArg2)); } + + inline void Logger::fatal(const char *pMessage, + const QString &rArg1, int arg2) const + { if (isEnabledFor(Level::FATAL_INT)) + forcedLog(Level::FATAL_INT, QString::fromUtf8(pMessage).arg(rArg1).arg(arg2)); } + + inline void Logger::fatal(const char *pMessage, + int arg1, + const QString &rArg2) const + { if (isEnabledFor(Level::FATAL_INT)) + forcedLog(Level::FATAL_INT, QString::fromUtf8(pMessage).arg(arg1).arg(rArg2)); } + + inline void Logger::fatal(const char *pMessage, + int arg1, + int arg2) const + { if (isEnabledFor(Level::FATAL_INT)) + forcedLog(Level::FATAL_INT, QString::fromUtf8(pMessage).arg(arg1).arg(arg2)); } + + inline void Logger::fatal(const char *pMessage, + const QString &rArg1, + const QString &rArg2, + const QString &rArg3) const + { if (isEnabledFor(Level::FATAL_INT)) + forcedLog(Level::FATAL_INT, QString::fromUtf8(pMessage).arg(rArg1, rArg2, rArg3)); } + + inline void Logger::fatal(const char *pMessage, + const QString &rArg1, + const QString &rArg2, + int arg3) const + { if (isEnabledFor(Level::FATAL_INT)) + forcedLog(Level::FATAL_INT, QString::fromUtf8(pMessage).arg(rArg1, rArg2).arg(arg3)); } + + inline void Logger::fatal(const char *pMessage, + const QString &rArg1, + int arg2, + const QString &rArg3) const + { if (isEnabledFor(Level::FATAL_INT)) + forcedLog(Level::FATAL_INT, QString::fromUtf8(pMessage).arg(rArg1).arg(arg2).arg(rArg3)); } + + inline void Logger::fatal(const char *pMessage, + const QString &rArg1, + int arg2, + int arg3) const + { if (isEnabledFor(Level::FATAL_INT)) + forcedLog(Level::FATAL_INT, QString::fromUtf8(pMessage).arg(rArg1).arg(arg2).arg(arg3)); } + + inline void Logger::fatal(const char *pMessage, + int arg1, + const QString &rArg2, + const QString &rArg3) const + { if (isEnabledFor(Level::FATAL_INT)) + forcedLog(Level::FATAL_INT, QString::fromUtf8(pMessage).arg(arg1).arg(rArg2).arg(rArg3)); } + + inline void Logger::fatal(const char *pMessage, + int arg1, + const QString &rArg2, + int arg3) const + { if (isEnabledFor(Level::FATAL_INT)) + forcedLog(Level::FATAL_INT, QString::fromUtf8(pMessage).arg(arg1).arg(rArg2).arg(arg3)); } + + inline void Logger::fatal(const char *pMessage, + int arg1, + int arg2, + const QString &rArg3) const + { if (isEnabledFor(Level::FATAL_INT)) + forcedLog(Level::FATAL_INT, QString::fromUtf8(pMessage).arg(arg1).arg(arg2).arg(rArg3)); } + + inline void Logger::fatal(const char *pMessage, + int arg1, + int arg2, + int arg3) const + { if (isEnabledFor(Level::FATAL_INT)) + forcedLog(Level::FATAL_INT, QString::fromUtf8(pMessage).arg(arg1).arg(arg2).arg(arg3)); } + + inline void Logger::fatal(const char *pMessage, + const QVariant &rArg1, + const QVariant &rArg2, + const QVariant &rArg3) const + { if (isEnabledFor(Level::FATAL_INT)) + forcedLog(Level::FATAL_INT, QString::fromUtf8(pMessage).arg(rArg1.toString(), rArg2.toString(), rArg3.toString())); } + + // Log operations: info + + inline void Logger::info(const QString &rMessage) const + { if (isEnabledFor(Level::INFO_INT)) + forcedLog(Level::INFO_INT, rMessage); } + + inline void Logger::info(const LogError &rLogError) const + { if (isEnabledFor(Level::INFO_INT)) + forcedLog(Level::INFO_INT, rLogError.toString()); } + + inline void Logger::info(const char *pMessage) const + { if (isEnabledFor(Level::INFO_INT)) + forcedLog(Level::INFO_INT, QString::fromUtf8(pMessage)); } + + inline void Logger::info(const char *pMessage, + const QString &rArg1) const + { if (isEnabledFor(Level::INFO_INT)) + forcedLog(Level::INFO_INT, QString::fromUtf8(pMessage).arg(rArg1)); } + + inline void Logger::info(const char *pMessage, + int arg1) const + { if (isEnabledFor(Level::INFO_INT)) + forcedLog(Level::INFO_INT, QString::fromUtf8(pMessage).arg(arg1)); } + + inline void Logger::info(const char *pMessage, + const QString &rArg1, + const QString &rArg2) const + { if (isEnabledFor(Level::INFO_INT)) + forcedLog(Level::INFO_INT, QString::fromUtf8(pMessage).arg(rArg1, rArg2)); } + + inline void Logger::info(const char *pMessage, + const QString &rArg1, + int arg2) const + { if (isEnabledFor(Level::INFO_INT)) + forcedLog(Level::INFO_INT, QString::fromUtf8(pMessage).arg(rArg1).arg(arg2)); } + + inline void Logger::info(const char *pMessage, + int arg1, + const QString &rArg2) const + { if (isEnabledFor(Level::INFO_INT)) + forcedLog(Level::INFO_INT, QString::fromUtf8(pMessage).arg(arg1).arg(rArg2)); } + + inline void Logger::info(const char *pMessage, + int arg1, + int arg2) const + { if (isEnabledFor(Level::INFO_INT)) + forcedLog(Level::INFO_INT, QString::fromUtf8(pMessage).arg(arg1).arg(arg2)); } + + inline void Logger::info(const char *pMessage, + const QString &rArg1, + const QString &rArg2, + const QString &rArg3) const + { if (isEnabledFor(Level::INFO_INT)) + forcedLog(Level::INFO_INT, QString::fromUtf8(pMessage).arg(rArg1, rArg2, rArg3)); } + + inline void Logger::info(const char *pMessage, + const QString &rArg1, + const QString &rArg2, + int arg3) const + { if (isEnabledFor(Level::INFO_INT)) + forcedLog(Level::INFO_INT, QString::fromUtf8(pMessage).arg(rArg1, rArg2).arg(arg3)); } + + inline void Logger::info(const char *pMessage, + const QString &rArg1, + int arg2, + const QString &rArg3) const + { if (isEnabledFor(Level::INFO_INT)) + forcedLog(Level::INFO_INT, QString::fromUtf8(pMessage).arg(rArg1).arg(arg2).arg(rArg3)); } + + inline void Logger::info(const char *pMessage, + const QString &rArg1, + int arg2, + int arg3) const + { if (isEnabledFor(Level::INFO_INT)) + forcedLog(Level::INFO_INT, QString::fromUtf8(pMessage).arg(rArg1).arg(arg2).arg(arg3)); } + + inline void Logger::info(const char *pMessage, + int arg1, + const QString &rArg2, + const QString &rArg3) const + { if (isEnabledFor(Level::INFO_INT)) + forcedLog(Level::INFO_INT, QString::fromUtf8(pMessage).arg(arg1).arg(rArg2).arg(rArg3)); } + + inline void Logger::info(const char *pMessage, + int arg1, + const QString &rArg2, + int arg3) const + { if (isEnabledFor(Level::INFO_INT)) + forcedLog(Level::INFO_INT, QString::fromUtf8(pMessage).arg(arg1).arg(rArg2).arg(arg3)); } + + inline void Logger::info(const char *pMessage, + int arg1, + int arg2, + const QString &rArg3) const + { if (isEnabledFor(Level::INFO_INT)) + forcedLog(Level::INFO_INT, QString::fromUtf8(pMessage).arg(arg1).arg(arg2).arg(rArg3)); } + + inline void Logger::info(const char *pMessage, + int arg1, + int arg2, + int arg3) const + { if (isEnabledFor(Level::INFO_INT)) + forcedLog(Level::INFO_INT, QString::fromUtf8(pMessage).arg(arg1).arg(arg2).arg(arg3)); } + + inline void Logger::info(const char *pMessage, + const QVariant &rArg1, + const QVariant &rArg2, + const QVariant &rArg3) const + { if (isEnabledFor(Level::INFO_INT)) + forcedLog(Level::INFO_INT, QString::fromUtf8(pMessage).arg(rArg1.toString(), rArg2.toString(), rArg3.toString())); } + + // Log operations: log + + inline void Logger::log(Level level, + const QString &rMessage) const + { if (isEnabledFor(level)) + forcedLog(level, rMessage); } + + inline void Logger::log(Level level, + const LogError &rLogError) const + { if (isEnabledFor(level)) + forcedLog(level, rLogError.toString()); } + + inline void Logger::log(Level level, + const char *pMessage) const + { if (isEnabledFor(level)) + forcedLog(level, QString::fromUtf8(pMessage)); } + + inline void Logger::log(Level level, + const char *pMessage, + const QString &rArg1) const + { if (isEnabledFor(level)) + forcedLog(level, QString::fromUtf8(pMessage).arg(rArg1)); } + + inline void Logger::log(Level level, + const char *pMessage, + int arg1) const + { if (isEnabledFor(level)) + forcedLog(level, QString::fromUtf8(pMessage).arg(arg1)); } + + inline void Logger::log(Level level, + const char *pMessage, + const QString &rArg1, + const QString &rArg2) const + { if (isEnabledFor(level)) + forcedLog(level, QString::fromUtf8(pMessage).arg(rArg1, rArg2)); } + + inline void Logger::log(Level level, + const char *pMessage, + const QString &rArg1, int arg2) const + { if (isEnabledFor(level)) + forcedLog(level, QString::fromUtf8(pMessage).arg(rArg1).arg(arg2)); } + + inline void Logger::log(Level level, + const char *pMessage, + int arg1, + const QString &rArg2) const + { if (isEnabledFor(level)) + forcedLog(level, QString::fromUtf8(pMessage).arg(arg1).arg(rArg2)); } + + inline void Logger::log(Level level, + const char *pMessage, + int arg1, + int arg2) const + { if (isEnabledFor(level)) + forcedLog(level, QString::fromUtf8(pMessage).arg(arg1).arg(arg2)); } + + inline void Logger::log(Level level, + const char *pMessage, + const QString &rArg1, + const QString &rArg2, + const QString &rArg3) const + { if (isEnabledFor(level)) + forcedLog(level, QString::fromUtf8(pMessage).arg(rArg1, rArg2, rArg3)); } + + inline void Logger::log(Level level, + const char *pMessage, + const QString &rArg1, + const QString &rArg2, + int arg3) const + { if (isEnabledFor(level)) + forcedLog(level, QString::fromUtf8(pMessage).arg(rArg1, rArg2).arg(arg3)); } + + inline void Logger::log(Level level, + const char *pMessage, + const QString &rArg1, + int arg2, + const QString &rArg3) const + { if (isEnabledFor(level)) + forcedLog(level, QString::fromUtf8(pMessage).arg(rArg1).arg(arg2).arg(rArg3)); } + + inline void Logger::log(Level level, + const char *pMessage, + const QString &rArg1, + int arg2, + int arg3) const + { if (isEnabledFor(level)) + forcedLog(level, QString::fromUtf8(pMessage).arg(rArg1).arg(arg2).arg(arg3)); } + + inline void Logger::log(Level level, + const char *pMessage, + int arg1, + const QString &rArg2, + const QString &rArg3) const + { if (isEnabledFor(level)) + forcedLog(level, QString::fromUtf8(pMessage).arg(arg1).arg(rArg2).arg(rArg3)); } + + inline void Logger::log(Level level, + const char *pMessage, + int arg1, + const QString &rArg2, + int arg3) const + { if (isEnabledFor(level)) + forcedLog(level, QString::fromUtf8(pMessage).arg(arg1).arg(rArg2).arg(arg3)); } + + inline void Logger::log(Level level, + const char *pMessage, + int arg1, + int arg2, + const QString &rArg3) const + { if (isEnabledFor(level)) + forcedLog(level, QString::fromUtf8(pMessage).arg(arg1).arg(arg2).arg(rArg3)); } + + inline void Logger::log(Level level, + const char *pMessage, + int arg1, + int arg2, + int arg3) const + { if (isEnabledFor(level)) + forcedLog(level, QString::fromUtf8(pMessage).arg(arg1).arg(arg2).arg(arg3)); } + + inline void Logger::log(Level level, + const char *pMessage, + const QVariant &rArg1, + const QVariant &rArg2, + const QVariant &rArg3) const + { if (isEnabledFor(level)) + forcedLog(level, QString::fromUtf8(pMessage).arg(rArg1.toString(), rArg2.toString(), rArg3.toString())); } + + // Log operations: trace + + inline void Logger::trace(const QString &rMessage) const + { if (isEnabledFor(Level::TRACE_INT)) + forcedLog(Level::TRACE_INT, rMessage); } + + inline void Logger::trace(const LogError &rLogError) const + { if (isEnabledFor(Level::TRACE_INT)) + forcedLog(Level::TRACE_INT, rLogError.toString()); } + + inline void Logger::trace(const char *pMessage) const + { if (isEnabledFor(Level::TRACE_INT)) + forcedLog(Level::TRACE_INT, QString::fromUtf8(pMessage)); } + + inline void Logger::trace(const char *pMessage, + const QString &rArg1) const + { if (isEnabledFor(Level::TRACE_INT)) + forcedLog(Level::TRACE_INT, QString::fromUtf8(pMessage).arg(rArg1)); } + + inline void Logger::trace(const char *pMessage, + int arg1) const + { if (isEnabledFor(Level::TRACE_INT)) + forcedLog(Level::TRACE_INT, QString::fromUtf8(pMessage).arg(arg1)); } + + inline void Logger::trace(const char *pMessage, + const QString &rArg1, + const QString &rArg2) const + { if (isEnabledFor(Level::TRACE_INT)) + forcedLog(Level::TRACE_INT, QString::fromUtf8(pMessage).arg(rArg1, rArg2)); } + + inline void Logger::trace(const char *pMessage, + const QString &rArg1, + int arg2) const + { if (isEnabledFor(Level::TRACE_INT)) + forcedLog(Level::TRACE_INT, QString::fromUtf8(pMessage).arg(rArg1).arg(arg2)); } + + inline void Logger::trace(const char *pMessage, + int arg1, + const QString &rArg2) const + { if (isEnabledFor(Level::TRACE_INT)) + forcedLog(Level::TRACE_INT, QString::fromUtf8(pMessage).arg(arg1).arg(rArg2)); } + + inline void Logger::trace(const char *pMessage, + int arg1, + int arg2) const + { if (isEnabledFor(Level::TRACE_INT)) + forcedLog(Level::TRACE_INT, QString::fromUtf8(pMessage).arg(arg1).arg(arg2)); } + + inline void Logger::trace(const char *pMessage, + const QString &rArg1, + const QString &rArg2, + const QString &rArg3) const + { if (isEnabledFor(Level::TRACE_INT)) + forcedLog(Level::TRACE_INT, QString::fromUtf8(pMessage).arg(rArg1, rArg2, rArg3)); } + + inline void Logger::trace(const char *pMessage, + const QString &rArg1, + const QString &rArg2, + int arg3) const + { if (isEnabledFor(Level::TRACE_INT)) + forcedLog(Level::TRACE_INT, QString::fromUtf8(pMessage).arg(rArg1, rArg2).arg(arg3)); } + + inline void Logger::trace(const char *pMessage, + const QString &rArg1, + int arg2, + const QString &rArg3) const + { if (isEnabledFor(Level::TRACE_INT)) + forcedLog(Level::TRACE_INT, QString::fromUtf8(pMessage).arg(rArg1).arg(arg2).arg(rArg3)); } + + inline void Logger::trace(const char *pMessage, + const QString &rArg1, + int arg2, + int arg3) const + { if (isEnabledFor(Level::TRACE_INT)) + forcedLog(Level::TRACE_INT, QString::fromUtf8(pMessage).arg(rArg1).arg(arg2).arg(arg3)); } + + inline void Logger::trace(const char *pMessage, + int arg1, + const QString &rArg2, + const QString &rArg3) const + { if (isEnabledFor(Level::TRACE_INT)) + forcedLog(Level::TRACE_INT, QString::fromUtf8(pMessage).arg(arg1).arg(rArg2).arg(rArg3)); } + + inline void Logger::trace(const char *pMessage, + int arg1, + const QString &rArg2, + int arg3) const + { if (isEnabledFor(Level::TRACE_INT)) + forcedLog(Level::TRACE_INT, QString::fromUtf8(pMessage).arg(arg1).arg(rArg2).arg(arg3)); } + + inline void Logger::trace(const char *pMessage, + int arg1, + int arg2, + const QString &rArg3) const + { if (isEnabledFor(Level::TRACE_INT)) + forcedLog(Level::TRACE_INT, QString::fromUtf8(pMessage).arg(arg1).arg(arg2).arg(rArg3)); } + + inline void Logger::trace(const char *pMessage, + int arg1, + int arg2, + int arg3) const + { if (isEnabledFor(Level::TRACE_INT)) + forcedLog(Level::TRACE_INT, QString::fromUtf8(pMessage).arg(arg1).arg(arg2).arg(arg3)); } + + inline void Logger::trace(const char *pMessage, + const QVariant &rArg1, + const QVariant &rArg2, + const QVariant &rArg3) const + { if (isEnabledFor(Level::TRACE_INT)) + forcedLog(Level::TRACE_INT, QString::fromUtf8(pMessage).arg(rArg1.toString(), rArg2.toString(), rArg3.toString())); } + + // Log operations: warn + + inline void Logger::warn(const QString &rMessage) const + { if (isEnabledFor(Level::WARN_INT)) + forcedLog(Level::WARN_INT, rMessage); } + + inline void Logger::warn(const LogError &rLogError) const + { if (isEnabledFor(Level::WARN_INT)) + forcedLog(Level::WARN_INT, rLogError.toString()); } + + inline void Logger::warn(const char *pMessage) const + { if (isEnabledFor(Level::WARN_INT)) + forcedLog(Level::WARN_INT, QString::fromUtf8(pMessage)); } + + inline void Logger::warn(const char *pMessage, + const QString &rArg1) const + { if (isEnabledFor(Level::WARN_INT)) + forcedLog(Level::WARN_INT, QString::fromUtf8(pMessage).arg(rArg1)); } + + inline void Logger::warn(const char *pMessage, + int arg1) const + { if (isEnabledFor(Level::WARN_INT)) + forcedLog(Level::WARN_INT, QString::fromUtf8(pMessage).arg(arg1)); } + + inline void Logger::warn(const char *pMessage, + const QString &rArg1, + const QString &rArg2) const + { if (isEnabledFor(Level::WARN_INT)) + forcedLog(Level::WARN_INT, QString::fromUtf8(pMessage).arg(rArg1, rArg2)); } + + inline void Logger::warn(const char *pMessage, + const QString &rArg1, + int arg2) const + { if (isEnabledFor(Level::WARN_INT)) + forcedLog(Level::WARN_INT, QString::fromUtf8(pMessage).arg(rArg1).arg(arg2)); } + + inline void Logger::warn(const char *pMessage, + int arg1, + const QString &rArg2) const + { if (isEnabledFor(Level::WARN_INT)) + forcedLog(Level::WARN_INT, QString::fromUtf8(pMessage).arg(arg1).arg(rArg2)); } + + inline void Logger::warn(const char *pMessage, + int arg1, + int arg2) const + { if (isEnabledFor(Level::WARN_INT)) + forcedLog(Level::WARN_INT, QString::fromUtf8(pMessage).arg(arg1).arg(arg2)); } + + inline void Logger::warn(const char *pMessage, + const QString &rArg1, + const QString &rArg2, + const QString &rArg3) const + { if (isEnabledFor(Level::WARN_INT)) + forcedLog(Level::WARN_INT, QString::fromUtf8(pMessage).arg(rArg1, rArg2, rArg3)); } + + inline void Logger::warn(const char *pMessage, + const QString &rArg1, + const QString &rArg2, + int arg3) const + { if (isEnabledFor(Level::WARN_INT)) + forcedLog(Level::WARN_INT, QString::fromUtf8(pMessage).arg(rArg1, rArg2).arg(arg3)); } + + inline void Logger::warn(const char *pMessage, + const QString &rArg1, + int arg2, + const QString &rArg3) const + { if (isEnabledFor(Level::WARN_INT)) + forcedLog(Level::WARN_INT, QString::fromUtf8(pMessage).arg(rArg1).arg(arg2).arg(rArg3)); } + + inline void Logger::warn(const char *pMessage, + const QString &rArg1, + int arg2, + int arg3) const + { if (isEnabledFor(Level::WARN_INT)) + forcedLog(Level::WARN_INT, QString::fromUtf8(pMessage).arg(rArg1).arg(arg2).arg(arg3)); } + + inline void Logger::warn(const char *pMessage, + int arg1, + const QString &rArg2, + const QString &rArg3) const + { if (isEnabledFor(Level::WARN_INT)) + forcedLog(Level::WARN_INT, QString::fromUtf8(pMessage).arg(arg1).arg(rArg2).arg(rArg3)); } + + inline void Logger::warn(const char *pMessage, + int arg1, + const QString &rArg2, + int arg3) const + { if (isEnabledFor(Level::WARN_INT)) + forcedLog(Level::WARN_INT, QString::fromUtf8(pMessage).arg(arg1).arg(rArg2).arg(arg3)); } + + inline void Logger::warn(const char *pMessage, + int arg1, + int arg2, + const QString &rArg3) const + { if (isEnabledFor(Level::WARN_INT)) + forcedLog(Level::WARN_INT, QString::fromUtf8(pMessage).arg(arg1).arg(arg2).arg(rArg3)); } + + inline void Logger::warn(const char *pMessage, + int arg1, + int arg2, + int arg3) const + { if (isEnabledFor(Level::WARN_INT)) + forcedLog(Level::WARN_INT, QString::fromUtf8(pMessage).arg(arg1).arg(arg2).arg(arg3)); } + + inline void Logger::warn(const char *pMessage, + const QVariant &rArg1, + const QVariant &rArg2, + const QVariant &rArg3) const + { if (isEnabledFor(Level::WARN_INT)) + forcedLog(Level::WARN_INT, QString::fromUtf8(pMessage).arg(rArg1.toString(), rArg2.toString(), rArg3.toString())); } + + +} // namespace Log4Qt + + +// Q_DECLARE_TYPEinfo(Log4Qt::Logger, Q_COMPLEX_TYPE); // Use default + + +#endif // LOG4QT_LOGGER_H diff --git a/src/log4qt/src/log4qt/loggerrepository.cpp b/src/log4qt/src/log4qt/loggerrepository.cpp new file mode 100644 index 0000000..b541bb2 --- /dev/null +++ b/src/log4qt/src/log4qt/loggerrepository.cpp @@ -0,0 +1,75 @@ +/****************************************************************************** + * + * package: Log4Qt + * file: loggerrepository.cpp + * created: September 2007 + * author: Martin Heinrich + * + * + * Copyright 2007 Martin Heinrich + * + * 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. + * + ******************************************************************************/ + + + +/****************************************************************************** + * Dependencies + ******************************************************************************/ + + +#include "log4qt/loggerrepository.h" + +#include + + + +namespace Log4Qt +{ + + + /************************************************************************** + * Declarations + **************************************************************************/ + + + + /************************************************************************** + * C helper functions + **************************************************************************/ + + + + /************************************************************************** + * Class implementation: LoggerRepository + **************************************************************************/ + + + + /************************************************************************** + * Implementation: Operators, Helper + **************************************************************************/ + + +#ifndef QT_NO_DEBUG_STREAM + QDebug operator<<(QDebug debug, + const LoggerRepository &rLoggerRepository) + { + return rLoggerRepository.debug(debug); + } +#endif // QT_NO_DEBUG_STREAM + + + +} // namespace Log4Qt diff --git a/src/log4qt/src/log4qt/loggerrepository.h b/src/log4qt/src/log4qt/loggerrepository.h new file mode 100644 index 0000000..13c0488 --- /dev/null +++ b/src/log4qt/src/log4qt/loggerrepository.h @@ -0,0 +1,128 @@ +/****************************************************************************** + * + * package: Log4Qt + * file: loggerrepository.h + * created: September 2007 + * author: Martin Heinrich + * + * + * Copyright 2007 Martin Heinrich + * + * 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. + * + ******************************************************************************/ + +#ifndef LOG4QT_LOGGERREPOSITORY_H +#define LOG4QT_LOGGERREPOSITORY_H + + +/****************************************************************************** + * Dependencies + ******************************************************************************/ + +#include +#include "log4qt/level.h" + + +/****************************************************************************** + * Declarations + ******************************************************************************/ + +namespace Log4Qt +{ + + class Logger; + + /*! + * \brief The class LoggerRepository is abstract base class for a logger + * repository. + */ + class LoggerRepository + { + public: + // LoggerRepository(); // Use compiler default + // LoggerRepository(const LoggerRepository &rOther); // Use compiler default + // virtual ~LoggerRepository(); // Use compiler default + // LoggerRepository &operator=(const LoggerRepository &rOther); // Use compiler default + + public: + virtual bool exists(const QString &rName) const = 0; + virtual Logger *logger(const QString &rName) = 0; + // JAVA: virtual Logger *logger(const String &rName, LoggerFactory *pFactory); + virtual QList loggers() const = 0; + virtual Logger *rootLogger() const = 0; + virtual Level threshold() const = 0; + virtual void setThreshold(Level level) = 0; + virtual void setThreshold(const QString &rThreshold) = 0; + + virtual bool isDisabled(Level level) = 0; + virtual void resetConfiguration() = 0; + virtual void shutdown() = 0; + + // JAVA: virtual void addHierarchyEventListener(HierarchyEventListener *pEventListener); + // JAVA: virtual void emitNoAppenderWarning(Logger *plogger) const; + // JAVA: virtual void fireAddAppenderEvent(Logger *plogger, Appender *pAppender) const; + + protected: +#ifndef QT_NO_DEBUG_STREAM + /*! + *\relates LoggerRepository + * + * Writes all object member variables to the given debug stream \a rDebug + * and returns the stream. + * + * The member function is used by + * QDebug operator<<(QDebug debug, const LoggerRepository &rLoggerRepository) + * to generate class specific output. + * + * \sa QDebug operator<<(QDebug debug, const LoggerRepository &rLoggerRepository) + */ + virtual QDebug debug(QDebug &rDebug) const = 0; + friend QDebug operator<<(QDebug debug, + const LoggerRepository &rLoggerRepository); +#endif + }; + + + /****************************************************************************** + * Operators, Helper + ******************************************************************************/ + +#ifndef QT_NO_DEBUG_STREAM + /*! + * \relates LoggerRepository + * Writes all object member variables to the given debug stream \a debug + * and returns the stream. + * + * To handle subclassing the function uses the virtual member function + * debug(). This allows each class to generate its own output. + * + * \sa QDebug, debug() + */ + QDebug operator<<(QDebug debug, + const LoggerRepository &rLoggerRepository); +#endif + + + /************************************************************************** + * Inline + **************************************************************************/ + + +} // namespace Log4Qt + + +// Q_DECLARE_TYPEINFO(Log4Qt::LoggerRepository, Q_COMPLEX_TYPE); // Use default + + +#endif // LOG4QT_LOGGERREPOSITORY_H diff --git a/src/log4qt/src/log4qt/loggingevent.cpp b/src/log4qt/src/log4qt/loggingevent.cpp new file mode 100644 index 0000000..161f01c --- /dev/null +++ b/src/log4qt/src/log4qt/loggingevent.cpp @@ -0,0 +1,272 @@ +/****************************************************************************** + * + * package: Log4Qt + * file: loggingevent.cpp + * created: September 2007 + * author: Martin Heinrich + * + * + * Copyright 2007 Martin Heinrich + * + * 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. + * + *****************************************************************************/ + + + +/****************************************************************************** + * Dependencies + ******************************************************************************/ + + +#include "log4qt/loggingevent.h" + +#include +#include +#include +#include +#include +#include +#include "log4qt/helpers/datetime.h" +#include "log4qt/helpers/initialisationhelper.h" +#include "log4qt/logger.h" +#include "log4qt/mdc.h" +#include "log4qt/ndc.h" + + + +namespace Log4Qt +{ + + + /************************************************************************** + * Declarations + **************************************************************************/ + + + LOG4QT_GLOBAL_STATIC(QMutex, sequence_guard) + + + + /************************************************************************** + * C helper functions + **************************************************************************/ + + + + /************************************************************************** + * Class implementation: LoggingEvent + **************************************************************************/ + + + LoggingEvent::LoggingEvent() : + mLevel(Level::NULL_INT), + mpLogger(0), + mMessage(), + mNdc(NDC::peek()), + mProperties(MDC::context()), + mSequenceNumber(nextSequenceNumber()), + mThreadName(), + mTimeStamp(DateTime::currentDateTime().toMilliSeconds()) + { + setThreadNameToCurrent(); + } + + + LoggingEvent::LoggingEvent(const Logger *pLogger, + Level level, + const QString &rMessage) : + mLevel(level), + mpLogger(pLogger), + mMessage(rMessage), + mNdc(NDC::peek()), + mProperties(MDC::context()), + mSequenceNumber(nextSequenceNumber()), + mThreadName(), + mTimeStamp(DateTime::currentDateTime().toMilliSeconds()) + { + setThreadNameToCurrent(); + } + + + LoggingEvent::LoggingEvent(const Logger *pLogger, + Level level, + const QString &rMessage, + qint64 timeStamp) : + mLevel(level), + mpLogger(pLogger), + mMessage(rMessage), + mNdc(NDC::peek()), + mProperties(MDC::context()), + mSequenceNumber(nextSequenceNumber()), + mThreadName(), + mTimeStamp(timeStamp) + { + setThreadNameToCurrent(); + } + + + LoggingEvent::LoggingEvent(const Logger *pLogger, + Level level, + const QString &rMessage, + const QString &rNdc, + const QHash &rProperties, + const QString &rThreadName, + qint64 timeStamp) : + mLevel(level), + mpLogger(pLogger), + mMessage(rMessage), + mNdc(rNdc), + mProperties(rProperties), + mSequenceNumber(nextSequenceNumber()), + mThreadName(rThreadName), + mTimeStamp(timeStamp) + { + } + + + QString LoggingEvent::loggerName() const + { + if (mpLogger) + return mpLogger->name(); + else + return QString(); + } + + + QString LoggingEvent::toString() const + { + return level().toString() + QLatin1Char(':') + message(); + } + + + qint64 LoggingEvent::sequenceCount() + { + QMutexLocker locker(sequence_guard()); + + return msSequenceCount; + } + + + qint64 LoggingEvent::startTime() + { + return InitialisationHelper::startTime(); + } + + + void LoggingEvent::setThreadNameToCurrent() + { + if (QThread::currentThread()) + mThreadName = QThread::currentThread()->objectName(); + } + + + qint64 LoggingEvent::nextSequenceNumber() + { + QMutexLocker locker(sequence_guard()); + + return ++msSequenceCount; + } + + + qint64 LoggingEvent::msSequenceCount = 0; + + + + /************************************************************************** + * Implementation: Operators, Helper + **************************************************************************/ + + +#ifndef QT_NO_DATASTREAM + QDataStream &operator<<(QDataStream &rStream, const LoggingEvent &rLoggingEvent) + { + QBuffer buffer; + buffer.open(QIODevice::WriteOnly); + QDataStream stream(&buffer); + + // version + quint16 version = 0; + stream << version; + // version 0 data + stream << rLoggingEvent.mLevel + << rLoggingEvent.loggerName() + << rLoggingEvent.mMessage + << rLoggingEvent.mNdc + << rLoggingEvent.mProperties + << rLoggingEvent.mSequenceNumber + << rLoggingEvent.mThreadName + << rLoggingEvent.mTimeStamp; + + buffer.close(); + rStream << buffer.buffer(); + return rStream; + } + + + QDataStream &operator>>(QDataStream &rStream, LoggingEvent &rLoggingEvent) + { + QByteArray array; + rStream >> array; + QBuffer buffer(&array); + buffer.open(QIODevice::ReadOnly); + QDataStream stream(&buffer); + + // version + quint16 version; + stream >> version; + // Version 0 data + QString logger; + stream >> rLoggingEvent.mLevel + >> logger + >> rLoggingEvent.mMessage + >> rLoggingEvent.mNdc + >> rLoggingEvent.mProperties + >> rLoggingEvent.mSequenceNumber + >> rLoggingEvent.mThreadName + >> rLoggingEvent.mTimeStamp; + if (logger.isEmpty()) + rLoggingEvent.mpLogger = 0; + else + rLoggingEvent.mpLogger = Logger::logger(logger); + + buffer.close(); + return rStream; + } +#endif // QT_NO_DATASTREAM + + +#ifndef QT_NO_DEBUG_STREAM + QDebug operator<<(QDebug debug, + const LoggingEvent &rLoggingEvent) + { + QString logger; + if (rLoggingEvent.logger() != 0) + logger = rLoggingEvent.logger()->name(); + + debug.nospace() << "LoggingEvent(" + << "level:" << rLoggingEvent.level().toString() << " " + << "logger:" << logger << " " + << "message:" << rLoggingEvent.message() << " " + << "sequencenumber:" << rLoggingEvent.sequenceNumber() << " " + << "threadname:" << rLoggingEvent.threadName() << " " + << "timestamp:" << rLoggingEvent.timeStamp() + << "(" << DateTime::fromMilliSeconds(rLoggingEvent.timeStamp()) << ")" + << "sequenceCount:" << rLoggingEvent.sequenceCount() + << ")"; + return debug.space(); + } +#endif // QT_NO_DEBUG_STREAM + + +} // namespace Log4Qt diff --git a/src/log4qt/src/log4qt/loggingevent.h b/src/log4qt/src/log4qt/loggingevent.h new file mode 100644 index 0000000..87e2ed6 --- /dev/null +++ b/src/log4qt/src/log4qt/loggingevent.h @@ -0,0 +1,221 @@ +/****************************************************************************** +* +* package: Log4Qt +* file: loggingevent.h +* created: September 2007 +* author: Martin Heinrich + * + * + * Copyright 2007 Martin Heinrich + * + * 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. + * +******************************************************************************/ + +#ifndef LOG4QT_LOG4QTEVENT_H +#define LOG4QT_LOG4QTEVENT_H + + +/****************************************************************************** + * Dependencies + ******************************************************************************/ + +#include +#include +#include +#include +#include "log4qt/level.h" + + +/****************************************************************************** + * Declarations + ******************************************************************************/ + +namespace Log4Qt +{ + + class Logger; + + /*! + * \brief The class LoggingEvent is the internal representation of a + * logging event. + * + * The class uses milliseconds since 1970-01-01T00:00:00, Coordinated + * Universal Time for time values. For converstion from and to QDateTime + * use DateTime. + */ + class LoggingEvent + { + public: + LoggingEvent(); + LoggingEvent(const Logger *pLogger, + Level level, + const QString &rMessage); + LoggingEvent(const Logger *pLogger, + Level level, + const QString &rMessage, + qint64 timeStamp); + LoggingEvent(const Logger *pLogger, + Level level, + const QString &rMessage, + const QString &rNdc, + const QHash &rProperties, + const QString &rThreadName, + qint64 timeStamp); + // LoggingEvent(const LoggingEvent &LoggingEvent::rOther); // Use compiler default + // virtual ~LoggingEvent(); // Use compiler default + // LoggingEvent &operator=(const LoggingEvent &LoggingEvent::rOther); // Use compiler default + + // JAVA: QString fqnOfLoggerClass() const; + Level level() const; + // LocationInformation locationInformation() const; + const Logger *logger() const; + QString message() const; + QHash mdc() const; + QString ndc() const; + QHash properties() const; + qint64 sequenceNumber() const; + QString threadName() const; + // JAVA: ThrowableInformation throwableInformation() const; + qint64 timeStamp() const; + + // JAVA: bool locationInformationExists() const; + QString loggerName() const; + QString property(const QString &rKey) const; + QStringList propertyKeys() const; + void setProperty(const QString &rKey, const QString &rValue); + // JAVA: QString throwableStrRep() const; + QString toString() const; + static qint64 sequenceCount(); + static qint64 startTime(); + + private: + void setThreadNameToCurrent(); + static qint64 nextSequenceNumber(); + + private: + Level mLevel; + const Logger *mpLogger; + QString mMessage; + QString mNdc; + QHash mProperties; + qint64 mSequenceNumber; + QString mThreadName; + qint64 mTimeStamp; + static qint64 msSequenceCount; + +#ifndef QT_NO_DATASTREAM + // Needs to be friend to stream objects + friend QDataStream &operator<<(QDataStream &rStream, + const LoggingEvent &rLoggingEvent); + friend QDataStream &operator>>(QDataStream &rStream, + LoggingEvent &rLoggingEvent); +#endif // QT_NO_DATASTREAM + }; + + + /************************************************************************** + * Operators, Helper + **************************************************************************/ + +#ifndef QT_NO_DATASTREAM + /*! + * \relates LoggingEvent + * + * Writes the given error \a rLoggingEvent to the given stream \a rStream, + * and returns a reference to the stream. + */ + QDataStream &operator<<(QDataStream &rStream, + const LoggingEvent &rLoggingEvent); + + /*! + * \relates LoggingEvent + * + * Reads an error from the given stream \a rStream into the given + * error \a rLoggingEvent, and returns a reference to the stream. + */ + QDataStream &operator>>(QDataStream &rStream, + LoggingEvent &rLoggingEvent); +#endif // QT_NO_DATASTREAM + +#ifndef QT_NO_DEBUG_STREAM + /*! + * \relates LoggingEvent + * + * Writes all object member variables to the given debug stream \a debug and + * returns the stream. + * + * + * %LoggingEvent(level:"WARN" logger:"Log4Qt::Properties" + * message:"Unknown escape sequence '\j' in property starting at line 1" + * sequencenumber:14 threadname:"main" + * timestamp:1194337148937(QDateTime("Tue Nov 6 03:19:08 2007") ) + * sequenceCount: 14 ) + * + * + * \sa QDebug + */ + QDebug operator<<(QDebug debug, + const LoggingEvent &rLoggingEvent); +#endif // QT_NO_DEBUG_STREAM + + + /************************************************************************** + * Inline + **************************************************************************/ + + inline Level LoggingEvent::level() const + { return mLevel; } + + inline const Logger *LoggingEvent::logger() const + { return mpLogger; } + + inline QString LoggingEvent::message() const + { return mMessage; } + + inline QHash LoggingEvent::mdc() const + { return mProperties; } + + inline QString LoggingEvent::ndc() const + { return mNdc; } + + inline QHash LoggingEvent::properties() const + { return mProperties; } + + inline qint64 LoggingEvent::sequenceNumber() const + { return mSequenceNumber; } + + inline QString LoggingEvent::threadName() const + { return mThreadName; } + + inline qint64 LoggingEvent::timeStamp() const + { return mTimeStamp; } + + inline QString LoggingEvent::property(const QString &rKey) const + { return mProperties.value(rKey); } + + inline QStringList LoggingEvent::propertyKeys() const + { return QStringList(mProperties.keys()); } + + inline void LoggingEvent::setProperty(const QString &rKey, const QString &rValue) + { mProperties.insert(rKey, rValue); } + + +} // namespace Log4Qt + + +Q_DECLARE_METATYPE(Log4Qt::LoggingEvent) +Q_DECLARE_TYPEINFO(Log4Qt::LoggingEvent, Q_MOVABLE_TYPE); + + +#endif // LOG4QT_LOG4QTEVENT_H diff --git a/src/log4qt/src/log4qt/logmanager.cpp b/src/log4qt/src/log4qt/logmanager.cpp new file mode 100644 index 0000000..47f2e2b --- /dev/null +++ b/src/log4qt/src/log4qt/logmanager.cpp @@ -0,0 +1,504 @@ +/****************************************************************************** + * + * package: Log4Qt + * file: logmanager.cpp + * created: September 2007 + * author: Martin Heinrich + * + * + * changes: Sep 2008, Martin Heinrich: + * - Resolved compilation problem with Microsoft Visual Studio 2005 + * Feb 2009, Martin Heinrich + * - Fixed VS 2008 unreferenced formal parameter warning by using + * Q_UNUSED in operator<<. + * + * + * Copyright 2007 - 2009 Martin Heinrich + * + * 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. + * + ******************************************************************************/ + + + +/****************************************************************************** + * Dependencies + ******************************************************************************/ + + +#include "log4qt/logmanager.h" + +#include +#include +#include +#include +#include +#include +#include "log4qt/consoleappender.h" +#include "log4qt/helpers/datetime.h" +#include "log4qt/helpers/initialisationhelper.h" +#include "log4qt/helpers/optionconverter.h" +#include "log4qt/hierarchy.h" +#include "log4qt/propertyconfigurator.h" +#include "log4qt/ttcclayout.h" +#include "log4qt/varia/denyallfilter.h" +#include "log4qt/varia/levelrangefilter.h" + + +namespace Log4Qt +{ + + + /************************************************************************** + * Declarations + **************************************************************************/ + + + + /************************************************************************** + * C helper functions + **************************************************************************/ + + + LOG4QT_DECLARE_STATIC_LOGGER(static_logger, Log4Qt::LogManager) + LOG4QT_GLOBAL_STATIC(QMutex, singleton_guard) + + + + /************************************************************************** + * Class implementation: LogManager + **************************************************************************/ + + + LogManager::LogManager() : + mObjectGuard(QMutex::Recursive), // Recursive for doStartup() to call doConfigureLogLogger() + mpLoggerRepository(new Hierarchy()), + mHandleQtMessages(false), + mOldQtMsgHandler(0) + { + } + + + LogManager::~LogManager() + { + static_logger()->warn("Unexpected destruction of LogManager"); + + // doSetConfigureHandleQtMessages(false); + // delete mpLoggerRepository; + } + + + Logger *LogManager::rootLogger() + { + return instance()->mpLoggerRepository->rootLogger(); + } + + + QList LogManager::loggers() + { + return instance()->mpLoggerRepository->loggers(); + } + + + Level LogManager::threshold() + { + return instance()->mpLoggerRepository->threshold(); + } + + + void LogManager::setThreshold(Level level) + { + instance()->mpLoggerRepository->setThreshold(level); + } + + + bool LogManager::exists(const char *pName) + { + return instance()->mpLoggerRepository->exists(QLatin1String(pName)); + } + + + LogManager *LogManager::instance() + { + // Do not use LOG4QT_GLOBAL_STATIC. The LogManager is rather expensive + // to construct, an exit handler must be set and doStartup must be + // called. + + if (!mspInstance) + { + QMutexLocker locker(singleton_guard()); + if (!mspInstance) + { + mspInstance = new LogManager; + // qAddPostRoutine(shutdown); + atexit(shutdown); + mspInstance->doConfigureLogLogger(); + mspInstance->welcome(); + mspInstance->doStartup(); + } + } + return mspInstance; + } + + + Logger *LogManager::logger(const QString &rName) + { + return instance()->mpLoggerRepository->logger(rName); + } + + + void LogManager::resetConfiguration() + { + setHandleQtMessages(false); + instance()->mpLoggerRepository->resetConfiguration(); + configureLogLogger(); + } + + + const char* LogManager::version() + { + return LOG4QT_VERSION_STR; + } + + + void LogManager::shutdown() + { + instance()->mpLoggerRepository->shutdown(); + } + + + void LogManager::doSetHandleQtMessages(bool handleQtMessages) + { + QMutexLocker locker(&mObjectGuard); + + if (instance()->mHandleQtMessages == handleQtMessages) + return; + + instance()->mHandleQtMessages = handleQtMessages; + if (instance()->mHandleQtMessages) + { + static_logger()->trace("Activate Qt message handling"); +#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0) + instance()->mOldQtMsgHandler = qInstallMsgHandler(qtMessageHandler); +#else + instance()->mOldQtMsgHandler = qInstallMessageHandler(qtMessageHandler); +#endif + } + else + { + static_logger()->trace("Deactivate Qt message handling"); +#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0) + qInstallMsgHandler(instance()->mOldQtMsgHandler); +#else + qInstallMessageHandler(instance()->mOldQtMsgHandler); +#endif + } + } + + + void LogManager::doConfigureLogLogger() + { + QMutexLocker locker(&instance()->mObjectGuard); + + // Level + QString value = InitialisationHelper::setting(QLatin1String("Debug"), + QLatin1String("ERROR")); + logLogger()->setLevel(OptionConverter::toLevel(value, Level::DEBUG_INT)); + + // Common layout + TTCCLayout *p_layout = new TTCCLayout(); + p_layout->setName(QLatin1String("LogLog TTCC")); + p_layout->setContextPrinting(false); + p_layout->activateOptions(); + + // Common deny all filter + Filter *p_denyall = new DenyAllFilter(); + p_denyall->activateOptions(); + + // ConsoleAppender on stdout for all events <= INFO + ConsoleAppender *p_appender; + LevelRangeFilter *p_filter; + p_appender = new ConsoleAppender(p_layout, ConsoleAppender::STDOUT_TARGET); + p_filter = new LevelRangeFilter(); + p_filter->setNext(p_denyall); + p_filter->setLevelMin(Level::NULL_INT); + p_filter->setLevelMax(Level::INFO_INT); + p_filter->activateOptions(); + p_appender->setName(QLatin1String("LogLog stdout")); + p_appender->addFilter(p_filter); + p_appender->activateOptions(); + logLogger()->addAppender(p_appender); + + // ConsoleAppender on stderr for all events >= WARN + p_appender = new ConsoleAppender(p_layout, ConsoleAppender::STDERR_TARGET); + p_filter = new LevelRangeFilter(); + p_filter->setNext(p_denyall); + p_filter->setLevelMin(Level::WARN_INT); + p_filter->setLevelMax(Level::OFF_INT); + p_filter->activateOptions(); + p_appender->setName(QLatin1String("LogLog stderr")); + p_appender->addFilter(p_filter); + p_appender->activateOptions(); + logLogger()->addAppender(p_appender); + } + + + void LogManager::doStartup() + { + QMutexLocker locker(&instance()->mObjectGuard); + + // Override + QString default_value = QLatin1String("false"); + QString value = InitialisationHelper::setting(QLatin1String("DefaultInitOverride"), + default_value); + if (value != default_value) + { + static_logger()->debug("DefaultInitOverride is set. Aborting default initialisation"); + return; + } + + // Configuration using setting Configuration + value = InitialisationHelper::setting(QLatin1String("Configuration")); + if (QFile::exists(value)) + { + static_logger()->debug("Default initialisation configures from file '%1' specified by Configure", value); + PropertyConfigurator::configure(value); + return; + } + + // Configuration using setting + if (QCoreApplication::instance()) + { + const QLatin1String log4qt_group("Log4Qt"); + const QLatin1String properties_group("Properties"); + QSettings s; + s.beginGroup(log4qt_group); + if (s.childGroups().contains(properties_group)) + { + const QString group(QLatin1String("Log4Qt/Properties")); + static_logger()->debug("Default initialisation configures from setting '%1/%2'", log4qt_group, properties_group); + s.beginGroup(properties_group); + PropertyConfigurator::configure(s); + return; + } + } + + // Configuration using default file + const QString default_file(QLatin1String("log4qt.properties")); + if (QFile::exists(default_file)) + { + static_logger()->debug("Default initialisation configures from default file '%1'", default_file); + PropertyConfigurator::configure(default_file); + return; + } + + static_logger()->debug("Default initialisation leaves package unconfigured"); + } + + + void LogManager::welcome() + { + static_logger()->info("Initialising Log4Qt %1", + QLatin1String(LOG4QT_VERSION_STR)); + + // Debug: Info + if (static_logger()->isDebugEnabled()) + { + // Create a nice timestamp with UTC offset + DateTime start_time = DateTime::fromMilliSeconds(InitialisationHelper::startTime()); + QString offset; + { + QDateTime utc = start_time.toUTC(); + QDateTime local = start_time.toLocalTime(); + QDateTime local_as_utc = QDateTime(local.date(), local.time(), Qt::UTC); + int min = utc.secsTo(local_as_utc) / 60; + if (min < 0) + offset += QLatin1Char('-'); + else + offset += QLatin1Char('+'); + min = abs(min); + offset += QString::number(min / 60).rightJustified(2, QLatin1Char('0')); + offset += QLatin1Char(':'); + offset += QString::number(min % 60).rightJustified(2, QLatin1Char('0')); + } + static_logger()->debug("Program startup time is %1 (UTC%2)", + start_time.toString(QLatin1String("ISO8601")), + offset); + static_logger()->debug("Internal logging uses the level %1", + logLogger()->level().toString()); + } + + // Trace: Dump settings + if (static_logger()->isTraceEnabled()) + { + static_logger()->trace("Settings from the system environment:"); + QString entry; + Q_FOREACH (entry, InitialisationHelper::environmentSettings().keys()) + static_logger()->trace(" %1: '%2'", + entry, + InitialisationHelper::environmentSettings().value(entry)); + + static_logger()->trace("Settings from the application settings:"); + if (QCoreApplication::instance()) + { + const QLatin1String log4qt_group("Log4Qt"); + const QLatin1String properties_group("Properties"); + static_logger()->trace(" %1:", log4qt_group); + QSettings s; + s.beginGroup(log4qt_group); + Q_FOREACH (entry, s.childKeys()) + static_logger()->trace(" %1: '%2'", + entry, + s.value(entry).toString()); + static_logger()->trace(" %1/%2:", log4qt_group, properties_group); + s.beginGroup(properties_group); + Q_FOREACH (entry, s.childKeys()) + static_logger()->trace(" %1: '%2'", + entry, + s.value(entry).toString()); + } else + static_logger()->trace(" QCoreApplication::instance() is not available"); + } + } + +#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0) + void LogManager::qtMessageHandler(QtMsgType type, const char *pMessage) + { + Level level; + switch (type) + { + case QtDebugMsg: + level = Level::DEBUG_INT; + break; + case QtWarningMsg: + level = Level::WARN_INT; + break; + case QtCriticalMsg: + level = Level::ERROR_INT; + break; + case QtFatalMsg: + level = Level::FATAL_INT; + break; + default: + level = Level::TRACE_INT; + } + instance()->qtLogger()->log(level, pMessage); + + // Qt fatal behaviour copied from global.cpp qt_message_output() + // begin { + + if ((type == QtFatalMsg) || + ((type == QtWarningMsg) && (!qgetenv("QT_FATAL_WARNINGS").isNull())) ) + { +#if defined(Q_CC_MSVC) && defined(QT_DEBUG) && defined(_DEBUG) && defined(_CRT_ERROR) + // get the current report mode + int reportMode = _CrtSetReportMode(_CRT_ERROR, _CRTDBG_MODE_WNDW); + _CrtSetReportMode(_CRT_ERROR, reportMode); + int ret = _CrtDbgReport(_CRT_ERROR, __FILE__, __LINE__, QT_VERSION_STR, pMessage); + if (ret == 0 && reportMode & _CRTDBG_MODE_WNDW) + return; // ignore + else if (ret == 1) + _CrtDbgBreak(); +#endif + +#if defined(Q_OS_UNIX) && defined(QT_DEBUG) + abort(); // trap; generates core dump +#else + exit(1); // goodbye cruel world +#endif + } + + // } end + } +#else + void LogManager::qtMessageHandler(QtMsgType type, const QMessageLogContext &context, const QString &message) + { + Level level; + switch (type) + { + case QtDebugMsg: + level = Level::DEBUG_INT; + break; + case QtWarningMsg: + level = Level::WARN_INT; + break; + case QtCriticalMsg: + level = Level::ERROR_INT; + break; + case QtFatalMsg: + level = Level::FATAL_INT; + break; + default: + level = Level::TRACE_INT; + } + QString newMsg = QString("%1:%2(%3)-").arg(context.file).arg(context.function).arg(context.line); + instance()->qtLogger()->log(level, newMsg+message); + + // Qt fatal behaviour copied from global.cpp qt_message_output() + // begin { + + if ((type == QtFatalMsg) || + ((type == QtWarningMsg) && (!qgetenv("QT_FATAL_WARNINGS").isNull())) ) + { +#if defined(Q_CC_MSVC) && defined(QT_DEBUG) && defined(_DEBUG) && defined(_CRT_ERROR) + // get the current report mode + int reportMode = _CrtSetReportMode(_CRT_ERROR, _CRTDBG_MODE_WNDW); + _CrtSetReportMode(_CRT_ERROR, reportMode); + int ret = _CrtDbgReport(_CRT_ERROR, __FILE__, __LINE__, QT_VERSION_STR, message.toUtf8().constData()); + if (ret == 0 && reportMode & _CRTDBG_MODE_WNDW) + return; // ignore + else if (ret == 1) + _CrtDbgBreak(); +#endif + +#if defined(Q_OS_UNIX) && defined(QT_DEBUG) + abort(); // trap; generates core dump +#else + exit(1); // goodbye cruel world +#endif + } + + // } end + } +#endif + + + + LogManager *LogManager::mspInstance = 0; + + + + /************************************************************************** + * Implementation: Operators, Helper + **************************************************************************/ + + +#ifndef QT_NO_DEBUG_STREAM + QDebug operator<<(QDebug debug, const LogManager &rLogManager) + { + Q_UNUSED(rLogManager); // To avoid warning C4100 on VS 2008 + QList loggers = rLogManager.loggers(); + debug.nospace() << "LogManager(" + << "loggerrepository:" << *rLogManager.loggerRepository() + << "log-level:" << rLogManager.logLogger()->level().toString() + << "log-appenders:" << rLogManager.logLogger()->appenders().count() + << "qt-level:" << rLogManager.qtLogger()->level().toString() + << "qt-appenders:" << rLogManager.qtLogger()->appenders().count() + << "handleqtmessages:" << rLogManager.handleQtMessages() + << ")"; + return debug.space(); + } +#endif // QT_NO_DEBUG_STREAM + + +} // namespace Log4Qt diff --git a/src/log4qt/src/log4qt/logmanager.h b/src/log4qt/src/log4qt/logmanager.h new file mode 100644 index 0000000..27111a0 --- /dev/null +++ b/src/log4qt/src/log4qt/logmanager.h @@ -0,0 +1,340 @@ +/****************************************************************************** + * + * package: Log4Qt + * file: logmanager.h + * created: September 2007 + * author: Martin Heinrich + * + * + * Copyright 2007 Martin Heinrich + * + * 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. + * + ******************************************************************************/ + +#ifndef LOG4QT_LOGMANAGER_H +#define LOG4QT_LOGMANAGER_H + + +/****************************************************************************** + * Dependencies + ******************************************************************************/ + +#include + +#include +#include +#include +#include +#include "log4qt/level.h" +#include "log4qt/logger.h" + + +/****************************************************************************** + * Declarations + ******************************************************************************/ + +namespace Log4Qt +{ + + class LoggerRepository; + + /*! + * \brief The class LogManager manages Logger in the default + * LoggerRepository. + * + * The LogManager manages logger in a single Hierarchy instance. It + * provides access to special logger over the logLogger(), qtLogger() + * and rootLogger() member functions. + * + * The LogManager is handling the initialisation on startup. The + * initialisation procedure will first attempt to configure the package + * based on environment variables. If the attempt fails it will check for + * the existence of configuration files in several location. For detailed + * description of the initialisation procedure see \ref Init + * "Initialization procedure". + * + * Messages created by qDebug(), qWarning(), qCritical() and qFatal() can + * be can be handled by the LogManager. By default the message handling + * is disabled. It can be enabled by calling setHandleQtMessages(). Once + * enabled all messages are logged using the logger qtLogger(). + * + * The Log4Qt runtime version is accessible over version(). The macros + * \ref Log4Qt::LOG4QT_VERSION "LOG4QT_VERSION" and + * \ref Log4Qt::LOG4QT_VERSION_STR "LOG4QT_VERSION_STR" provide the + * compile time version. + * + * \note All the functions declared in this class are thread-safe. + */ + class LogManager + { + private: + LogManager(); + LogManager(const LogManager &rOther); // Not implemented + virtual ~LogManager(); + LogManager &operator=(const LogManager &rOther); // Not implemented + + public: + /*! + * Returns if the handling of messages created by calls to qDebug(), + * qWarning(), qCritical() and qFatal() is activated. + * + * \sa setHandleQtMessages() + */ + static bool handleQtMessages(); + + static LoggerRepository *loggerRepository(); + + /*! + * Returns the logger used for logging internal messages. See + * \ref LogLog "Logging within the package" for more details. + * + * Calling this function is equivalent to calling logger("Log4Qt"). + */ + static Logger *logLogger(); + + /*! + * Returns a pointer to the logger used for logging messages created by + * calls to qDebug(), qWarning(), qCritical() and qFatal(). + * + * Calling this function is equivalent to calling logger("Qt"). + * + * \sa setHandleQtMessages() + */ + static Logger *qtLogger(); + + static Logger *rootLogger(); + static QList loggers(); + static Level threshold(); + static void setThreshold(Level level); + + /*! + * Activates or deactivates the handling of messages created by calls + * to qDebug(), qWarning(), qCritical() and qFatal() is activated. + * + * If activated, a Qt message handler is installed. Messages are logged + * using the logger returned by qtLogger(). For fatal messages the same + * exit procedure is implemented as for qFatal(). + * + * The following mappping is used from QtMsgType to Level: + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + *
    QtMsgType     %Level
QtDebugMsg Level::DEBUG_INT
QtWarningMsg Level::WARN_INT
QtCriticalMsg Level::ERROR_INT
QtFatalMsg Level::FATAL_INT
QtSystemMsg Level::TRACE_INT
+ * + * The default value is false for not handling Qt messages. + * + * \sa handleQtMessages(), qInstallMsgHandler(), qFatal() + */ + static void setHandleQtMessages(bool handleQtMessages); + + /*! + * Configures the logging for the package to its default behaviour. + * + * The logger logLogger() is configured to be not additive. Messages + * with the level Level::ERROR_INT and Level::FATAL_INT are written + * to \c stderr using a ConsoleAppender. The remaining messages are + * written to \c stdout using a second ConsoleAppender. The level is + * read from the system environment or application settings using + * InitialisationHelper::setting() with the key \c Debug. If a level + * value is found, but it is not a valid Level string, + * Level::DEBUG_INT is used. If no level string is found + * Level::ERROR_INT is used. + * + * The function does not remove any appender from the logger + * logLogger(). + * + * \sa \ref LogLog "Logging within the package", + * \ref Env "Environment Variables", + * resetConfiguration(), InitialisationHelper::setting() + */ + static void configureLogLogger(); + + static bool exists(const char *pName); + // JAVA: void fireAddAppenderEvent(Logger *pLogger, Appender *pAppender); + + /*! + * Returns the LogManager instance. + */ + static LogManager *instance(); + + static Logger *logger(const QString &rName); + + /*! + * Reset all values contained in logger repository to their default. + * + * All appenders are removed from all loggers. The loggers are handled + * in no particular order. The last loggers to be reset are qtLogger(), + * logLogger() and rootLogger() in that order. + * + * The handling of messages created by calls to qDebug(), qWarning(), + * qCritical() and qFatal() is deactivated. + * + * The internal logging is initialised to its default bahaviour + * using configureLogLogger(). + * + * \sa LoggerRepository::resetConfiguration(), setHandleQtMessages(), + * configureLogLogger() + */ + static void resetConfiguration(); + + static void shutdown(); + + /*! + * Executes the default initialisation procedure of the package. + * + * The function will test for the setting \c DefaultInitOverride in + * the system environment and application settings using + * \ref InitialisationHelper::setting(). If the value is present and + * set to anything else then \c false, the initialisation is aborted. + *
+ * The system environment and application settings are tested for the + * setting \c Configuration. If it is found and it is a valid path to + * a file, the package is configured with the file using + * \ref PropertyConfigurator::doConfigure(const QString &, LoggerRepository *) + * "PropertyConfigurator::doConfigure()". If the setting + * \c Configuration is not available and a QCoreApplication object is + * present, the application settings are tested for a group + * \c Log4Qt/Properties. If the group exists, the package is configured + * with the setting using the + * \ref PropertyConfigurator::doConfigure(const QSettings &r, LoggerRepository *) + * "PropertyConfiguratordoConfigure()". If neither a configuration + * file nor configuration settings could be found, the current working + * directory is searched for the file \c "log4qt.properties". If it is + * found, the package is configured with the file using + * \ref PropertyConfigurator::doConfigure(const QString &, LoggerRepository *) + * "PropertyConfigurator::doConfigure()". + * + * \sa \ref Init "Initialization procedure", + * \ref Env "Environment Variables", + * InitialisationHelper::setting() + */ + static void startup(); + + /*! + * Returns the version number of Log4Qt at run-time. This may be a + * different version than the version the application was compiled + * against. + * + * \sa \ref Log4Qt::LOG4QT_VERSION "LOG4QT_VERSION", + * \ref Log4Qt::LOG4QT_VERSION_STR "LOG4QT_VERSION_STR" + + */ + static const char* version(); + + private: + void doSetHandleQtMessages(bool handleQtMessages); + void doConfigureLogLogger(); + void doStartup(); + void welcome(); +#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0) + static void qtMessageHandler(QtMsgType type, + const char *pMessage); +#else + static void qtMessageHandler(QtMsgType type, + const QMessageLogContext &context, + const QString &message); +#endif + + + private: + mutable QMutex mObjectGuard; + LoggerRepository *mpLoggerRepository; + Logger *mpNullLogger; + bool mHandleQtMessages; +#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0) + QtMsgHandler mOldQtMsgHandler; +#else + QtMessageHandler mOldQtMsgHandler; +#endif + static LogManager *mspInstance; + }; + + + /*************************************************************************** + * Operators, Helper + ***************************************************************************/ + + #ifndef QT_NO_DEBUG_STREAM + /*! + * \relates LogManager + * + * Writes all object member variables to the given debug stream \a rDebug and + * returns the stream. + * + * + * %LogManager(loggerrepository:Hierarchy(loggers:6 root-level:"DEBUG" + * root-appenders:0 log-level: "NULL" log-appenders:0 + * qt-level: "NULL" qt-appenders:0 handleqtmessages: false ) + * + * \sa QDebug + */ + QDebug operator<<(QDebug debug, + const LogManager &rLogManager); + #endif // QT_NO_DEBUG_STREAM + + + /************************************************************************** + * Inline + **************************************************************************/ + + inline LoggerRepository *LogManager::loggerRepository() + { // QMutexLocker locker(&instance()->mObjectGuard); // Constant for object lifetime + return instance()->mpLoggerRepository; } + + inline bool LogManager::handleQtMessages() + { // QMutexLocker locker(&instance()->mObjectGuard); // Read/Write of bool is safe + return instance()->mHandleQtMessages; } + + inline Logger *LogManager::logLogger() + { // QMutexLocker locker(&instance()->mObjectGuard); // Constant for object lifetime + return logger(QLatin1String("Log4Qt")); } + + inline Logger *LogManager::qtLogger() + { // QMutexLocker locker(&instance()->mObjectGuard); // Constant for object lifetime + return logger(QLatin1String("Qt")); } + + inline void LogManager::setHandleQtMessages(bool handleQtMessages) + { instance()->doSetHandleQtMessages(handleQtMessages); } + + inline void LogManager::configureLogLogger() + { instance()->doConfigureLogLogger(); } + + inline void LogManager::startup() + { instance()->doStartup(); } + +} // namespace Log4Qt + + +// Q_DECLARE_TYPEINFO(Log4Qt::LogManager, Q_COMPLEX_TYPE); // Use default + + +#endif // LOG4QT_LOGMANAGER_H diff --git a/src/log4qt/src/log4qt/mdc.cpp b/src/log4qt/src/log4qt/mdc.cpp new file mode 100644 index 0000000..5ba2ba8 --- /dev/null +++ b/src/log4qt/src/log4qt/mdc.cpp @@ -0,0 +1,116 @@ +/****************************************************************************** + * + * package: Log4Qt + * file: mdc.cpp + * created: September 2007 + * author: Martin Heinrich + * + * + * changes Feb 2009, Martin Heinrich + * - Fixed unreferenced formal parameter warning by using + * Q_UNUSED in operator<<. + * + * + * Copyright 2007 - 2009 Martin Heinrich + * + * 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. + * + *****************************************************************************/ + + + +/****************************************************************************** + * Dependencies + ******************************************************************************/ + + +#include "log4qt/mdc.h" + +#include +#include +#include +#include "log4qt/helpers/initialisationhelper.h" +#include "log4qt/logger.h" + + + +namespace Log4Qt +{ + + + /************************************************************************** + * Declarations + **************************************************************************/ + + + + /************************************************************************** + * C helper functions + **************************************************************************/ + + + + /************************************************************************** + * Class implementation: MDC + **************************************************************************/ + + + QString MDC::get(const QString &rKey) + { + if (!instance()->mHash.hasLocalData()) + return QString(); + + return instance()->mHash.localData()->value(rKey); + } + + + QHash MDC::context() + { + if (!instance()->mHash.hasLocalData()) + return QHash(); + + return *instance()->mHash.localData(); + } + + + LOG4QT_IMPLEMENT_INSTANCE(MDC) + + + QHash *MDC::localData() + { + if (!instance()->mHash.hasLocalData()) + instance()->mHash.setLocalData(new QHash); + return instance()->mHash.localData(); + } + + + + /************************************************************************** + * Implementation: Operators, Helper + **************************************************************************/ + + +#ifndef QT_NO_DEBUG_STREAM + QDebug operator<<(QDebug debug, const MDC &rMDC) + { + Q_UNUSED(rMDC); // To avoid warning C4100 on VS 2008 + debug.nospace() << "MDC(" + << "thread:" << QThread::currentThread()->objectName() << " " + << "context:" << rMDC.context() + << ")"; + return debug.space(); + } +#endif // QT_NO_DEBUG_STREAM + + +} // namespace Log4Qt diff --git a/src/log4qt/src/log4qt/mdc.h b/src/log4qt/src/log4qt/mdc.h new file mode 100644 index 0000000..5e8fce9 --- /dev/null +++ b/src/log4qt/src/log4qt/mdc.h @@ -0,0 +1,122 @@ +/****************************************************************************** + * + * package: Log4Qt + * file: mdc.h + * created: September 2007 + * author: Martin Heinrich + * + * + * Copyright 2007 Martin Heinrich + * + * 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. + * + ******************************************************************************/ + +#ifndef LOG4QT_MDC_H +#define LOG4QT_MDC_H + + +/****************************************************************************** + * Dependencies + ******************************************************************************/ + +#include +#include +#include +#include "log4qt/log4qt.h" + + +/****************************************************************************** + * Declarations + ******************************************************************************/ + +namespace Log4Qt +{ + + +/*! + * \brief The class MDC implements a mapped diagnostic context. + * + * \note All the functions declared in this class are thread-safe. + */ + class MDC + { + private: + MDC(); + MDC(const MDC &rOther); // Not implemented + // virtual ~MDC(); // Use compiler default + MDC &operator=(const MDC &rOther); // Not implemented + + public: + static QString get(const QString &rKey); + static QHash context(); + + /*! + * Returns the MDC instance. + */ + static MDC *instance(); + + static void put(const QString &rKey, const QString &rValue); + static void remove(const QString &rKey); + + private: + static QHash *localData(); + + private: + QThreadStorage< QHash * > mHash; + }; + + + /************************************************************************** + * Operators, Helper + **************************************************************************/ + + #ifndef QT_NO_DEBUG_STREAM + /*! + * \relates MDC + * + * Writes all object member variables to the given debug stream \a rDebug + * and returns the stream. + * + * + * %MDC(thread:"main" context:QHash(("login", "Peter")("database", "UAT")) ) + * + * \sa QDebug + */ + QDebug operator<<(QDebug debug, + const MDC &rMDC); + #endif // QT_NO_DEBUG_STREAM + + + /************************************************************************** + * Inline + **************************************************************************/ + + inline MDC::MDC() : + mHash() + {} + + inline void MDC::put(const QString &rKey, const QString &rValue) + { localData()->insert(rKey, rValue); } + + inline void MDC::remove(const QString &rKey) + { localData()->remove(rKey); } + + +} // namespace Log4Qt + + +// Q_DECLARE_TYPEINFO(Log4Qt::MDC, Q_COMPLEX_TYPE); // Use default + + +#endif // LOG4QT_MDC_H diff --git a/src/log4qt/src/log4qt/ndc.cpp b/src/log4qt/src/log4qt/ndc.cpp new file mode 100644 index 0000000..17ebd47 --- /dev/null +++ b/src/log4qt/src/log4qt/ndc.cpp @@ -0,0 +1,154 @@ +/****************************************************************************** + * + * package: Log4Qt + * file: ndc.cpp + * created: September 2007 + * author: Martin Heinrich + * + * + * changes Feb 2009, Martin Heinrich + * - Fixed VS 2008 unreferenced formal parameter warning by using + * Q_UNUSED in operator<<. + * + * + * Copyright 2007 - 2009 Martin Heinrich + * + * 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. + * + *****************************************************************************/ + + + +/****************************************************************************** + * Dependencies + ******************************************************************************/ + + +#include "log4qt/ndc.h" + +#include +#include +#include +#include "log4qt/helpers/initialisationhelper.h" +#include "log4qt/logger.h" + + + +namespace Log4Qt +{ + + + /************************************************************************** + * Declarations + **************************************************************************/ + + + + /************************************************************************** + * C helper functions + **************************************************************************/ + + + LOG4QT_DECLARE_STATIC_LOGGER(logger, Log4Qt:NDC) + + + + /************************************************************************** + * Class implementation: NDC + **************************************************************************/ + + + void NDC::clear() + { + if (!instance()->mStack.hasLocalData()) + return; + + instance()->mStack.localData()->clear(); + } + + + int NDC::depth() + { + if (!instance()->mStack.hasLocalData()) + return 0; + + return instance()->mStack.localData()->count(); + } + + + LOG4QT_IMPLEMENT_INSTANCE(NDC) + + + QString NDC::pop() + { + if (!instance()->mStack.hasLocalData() || instance()->mStack.localData()->isEmpty()) + { + logger()->warn("Requesting pop from empty NDC stack"); + return QString(); + } + + return instance()->mStack.localData()->pop(); + } + + + void NDC::push(const QString &rMessage) + { + if (!instance()->mStack.hasLocalData()) + instance()->mStack.setLocalData(new QStack); + + instance()->mStack.localData()->push(rMessage); + } + + + void NDC::setMaxDepth(int maxDepth) + { + if (!instance()->mStack.hasLocalData() || + instance()->mStack.localData()->size() <= maxDepth) + return; + + instance()->mStack.localData()->resize(maxDepth); + } + + + QString NDC::peek() + { + if (!instance()->mStack.hasLocalData() || + instance()->mStack.localData()->isEmpty()) + return QString(); + + return instance()->mStack.localData()->top(); + } + + + + /************************************************************************** + * Implementation: Operators, Helper + **************************************************************************/ + + +#ifndef QT_NO_DEBUG_STREAM + QDebug operator<<(QDebug debug, + const NDC &rNDC) + { + Q_UNUSED(rNDC); // To avoid warning C4100 on VS 2008 + debug.nospace() << "NDC(" + << "thread:" << QThread::currentThread()->objectName() << " " + << "peek:" << rNDC.peek() << " " + << "depth:" << rNDC.depth() + << ")"; + return debug.space(); + } +#endif // QT_NO_DEBUG_STREAM + + +} // namespace Log4Qt diff --git a/src/log4qt/src/log4qt/ndc.h b/src/log4qt/src/log4qt/ndc.h new file mode 100644 index 0000000..e2c4210 --- /dev/null +++ b/src/log4qt/src/log4qt/ndc.h @@ -0,0 +1,121 @@ +/****************************************************************************** + * + * package: Log4Qt + * file: ndc.h + * created: September 2007 + * author: Martin Heinrich + * + * + * Copyright 2007 Martin Heinrich + * + * 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. + * + ******************************************************************************/ + +#ifndef LOG4QT_NDC_H +#define LOG4QT_NDC_H + + +/****************************************************************************** + * Dependencies + ******************************************************************************/ + +#include +#include +#include +#include "log4qt/log4qt.h" + + +/****************************************************************************** + * Declarations + ******************************************************************************/ + +namespace Log4Qt +{ + + /*! + * \brief The class NDC implements a nested diagnostic context. + * + * The method remove() is not required. QThreadStorage cleans up on thread + * exit. + * + * \note All the functions declared in this class are thread-safe. + */ + class NDC + { + private: + NDC(); + NDC(const NDC &rOther); // Not implemented + // virtual ~NDC(); // Use compiler default + NDC &operator=(const NDC &rOther); // Not implemented + + public: + static void clear(); + // JAVA: static QStack cloneStack(); + // JAVA: static QString get(); + static int depth(); + // JAVA: inherit(Stack stack) + + /*! + * Returns the NDC instance. + */ + static NDC *instance(); + + static QString pop(); + static void push(const QString &rMessage); + // JAVA: static void remove(); // Not required + static void setMaxDepth(int maxDepth); + static QString peek(); + + private: + QThreadStorage< QStack * > mStack; + }; + + + /****************************************************************************** + * Operators, Helper + ******************************************************************************/ + + #ifndef QT_NO_DEBUG_STREAM + /*! + * \relates NDC + * + * Writes all object member variables to the given debug stream \a rDebug and + * returns the stream. + * + * + * %NDC(thread:"main" peek:"i = 3" depth:4) + * + * \sa QDebug + */ + QDebug operator<<(QDebug debug, + const NDC &rNDC); + #endif // QT_NO_DEBUG_STREAM + + + /****************************************************************************** + * Inline + ******************************************************************************/ + + inline NDC::NDC() : + mStack() + {} + + +} // namespace Log4Qt + + +// Q_DECLARE_TYPEINFO(Log4Qt::NDC, Q_COMPLEX_TYPE); // Use default + + +#endif // LOG4QT_NDC_H diff --git a/src/log4qt/src/log4qt/patternlayout.cpp b/src/log4qt/src/log4qt/patternlayout.cpp new file mode 100644 index 0000000..a93099f --- /dev/null +++ b/src/log4qt/src/log4qt/patternlayout.cpp @@ -0,0 +1,147 @@ +/****************************************************************************** + * + * package: Log4Qt + * file: patternlayout.cpp + * created: September 2007 + * author: Martin Heinrich + * + * + * Copyright 2007 Martin Heinrich + * + * 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. + * + ******************************************************************************/ + + + +/****************************************************************************** + * Dependencies + ******************************************************************************/ + + +#include "log4qt/patternlayout.h" + +#include +#include "log4qt/helpers/patternformatter.h" +#include "log4qt/loggingevent.h" + + + +namespace Log4Qt +{ + + + /************************************************************************** + * Declarations + **************************************************************************/ + + + + /************************************************************************** + * C helper functions + **************************************************************************/ + + + + /************************************************************************** + * Class implementation: PatternLayout + **************************************************************************/ + + + PatternLayout::PatternLayout(QObject *pParent) : + Layout(pParent), + mPattern(), + mpPatternFormatter(0) + { + setConversionPattern(DEFAULT_CONVERSION_PATTERN); + } + + + PatternLayout::PatternLayout(const QString &rPattern, + QObject *pParent) : + Layout(pParent), + mPattern(), + mpPatternFormatter(0) + { + setConversionPattern(rPattern); + } + + + PatternLayout::PatternLayout(ConversionPattern conversionPattern, + QObject *pParent) : + Layout(pParent), + mPattern(), + mpPatternFormatter(0) + { + setConversionPattern(conversionPattern); + } + + + PatternLayout::~PatternLayout() + { + delete mpPatternFormatter; + } + + + void PatternLayout::setConversionPattern(ConversionPattern conversionPattern) + { + switch (conversionPattern) + { + case DEFAULT_CONVERSION_PATTERN: + setConversionPattern(QLatin1String("%m%n")); + break; + case TTCC_CONVERSION_PATTERN: + setConversionPattern(QLatin1String("%r [%t] %p %c %x - %m%n")); + break; + default: + Q_ASSERT_X(false, "PatternLayout::setConversionFormat", "Unkown ConversionFormat"); + setConversionPattern(QString()); + } + } + + + QString PatternLayout::format(const LoggingEvent &rEvent) + { + Q_ASSERT_X(mpPatternFormatter, "PatternLayout::format()", "mpPatternConverter must not be null"); + + return mpPatternFormatter->format(rEvent); + } + + + void PatternLayout::updatePatternFormatter() + { + delete mpPatternFormatter; + mpPatternFormatter = new PatternFormatter(mPattern); + } + + +#ifndef QT_NO_DEBUG_STREAM + QDebug PatternLayout::debug(QDebug &rDebug) const + { + rDebug.nospace() << "PatternLayout(" + << "name:" << name() << " " + << "pattern:" << conversionPattern() << " " + << "referencecount:" << referenceCount() + << ")"; + return rDebug.space(); + } +#endif // QT_NO_DEBUG_STREAM + + + + /************************************************************************** + * Implementation: Operators, Helper + **************************************************************************/ + + +} // namespace Log4Qt diff --git a/src/log4qt/src/log4qt/patternlayout.h b/src/log4qt/src/log4qt/patternlayout.h new file mode 100644 index 0000000..2152f4b --- /dev/null +++ b/src/log4qt/src/log4qt/patternlayout.h @@ -0,0 +1,159 @@ +/****************************************************************************** + * + * package: Log4Qt + * file: patternlayout.h + * created: September 2007 + * author: Martin Heinrich + * + * + * Copyright 2007 Martin Heinrich + * + * 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. + * + ******************************************************************************/ + +#ifndef LOG4QT_PATTERNLAYOUT_H +#define LOG4QT_PATTERNLAYOUT_H + + +/****************************************************************************** + * Dependencies + ******************************************************************************/ + +#include "log4qt/layout.h" + + +/****************************************************************************** + * Declarations + ******************************************************************************/ + + +namespace Log4Qt +{ + + class PatternFormatter; + + /*! + * \brief The class PatternLayout outputs a logging event based on a + * pattern string. + * + * \note The ownership and lifetime of objects of this class are managed. + * See \ref Ownership "Object ownership" for more details. + */ + class PatternLayout : public Layout + { + Q_OBJECT + + /*! + * The property holds the conversion pattern used by the appender. + * + * The default is "%m%n". + * + * \sa conversionPattern(), setConversionPattern() + */ + Q_PROPERTY(QString conversionPattern READ conversionPattern WRITE setConversionPattern) + + public: + /*! + * The enum ConversionPattern defines constants for pattern strings. + * + * \sa setConversionPattern(ConversionPattern); + */ + enum ConversionPattern + { + /*! The default conversion pattern string is "%m,%n". */ + DEFAULT_CONVERSION_PATTERN, + /*! + * The ttcc conversion pattern string is + * "%r [%t] %p %c %x - %m%n". + */ + TTCC_CONVERSION_PATTERN, + }; + Q_ENUMS(ConversionPattern) + + PatternLayout(QObject *pParent = 0); + PatternLayout(const QString &rPattern, + QObject *pParent = 0); + + /*! + * Creates a PatternLayout with the conversion pattern value specified + * by the \a conversionPattern constant. + */ + PatternLayout(ConversionPattern conversionPattern, + QObject *pParent = 0); + + virtual ~PatternLayout(); + private: + PatternLayout(const PatternLayout &rOther); // Not implemented + PatternLayout &operator=(const PatternLayout &rOther); // Not implemented + + public: + QString conversionPattern() const; + void setConversionPattern(const QString &rPattern); + + /*! + * Sets the conversion pattern to the value specified by the + * \a conversionPattern constant. + */ + void setConversionPattern(ConversionPattern conversionPattern); + + virtual QString format(const LoggingEvent &rEvent); + + protected: +#ifndef QT_NO_DEBUG_STREAM + /*! + * Writes all object member variables to the given debug stream + * \a rDebug and returns the stream. + * + * + * %PatternLayout(name:"PL" pattern:"%r [%t] %p %c %x - %m%n" + * "referencecount:3") + * + * \sa QDebug, operator<<(QDebug debug, const LogObject &rLogObject) + */ + virtual QDebug debug(QDebug &rDebug) const; +#endif // QT_NO_DEBUG_STREAM + + private: + void updatePatternFormatter(); + + private: + QString mPattern; + PatternFormatter *mpPatternFormatter; + }; + + + /************************************************************************** + * Operators, Helper + **************************************************************************/ + + + /************************************************************************** + * Inline + **************************************************************************/ + + inline QString PatternLayout::conversionPattern() const + { return PatternLayout::mPattern; } + + inline void PatternLayout::setConversionPattern(const QString &rPattern) + { mPattern = rPattern; + updatePatternFormatter(); } + + +} // namespace Log4Qt + + +// Q_DECLARE_TYPEINFO(Log4Qt::PatternLayout, Q_COMPLEX_TYPE); // Use default + + +#endif // LOG4QT_PATTERNLAYOUT_H diff --git a/src/log4qt/src/log4qt/propertyconfigurator.cpp b/src/log4qt/src/log4qt/propertyconfigurator.cpp new file mode 100644 index 0000000..19b7113 --- /dev/null +++ b/src/log4qt/src/log4qt/propertyconfigurator.cpp @@ -0,0 +1,588 @@ +/****************************************************************************** + * + * package: Logging + * file: propertyconfigurator.cpp + * created: September 2007 + * author: Martin Heinrich + * + * + * changes Feb 2009, Martin Heinrich + * - Fixed VS 2008 unreferenced formal parameter warning by using + * Q_UNUSED in operator<<. + * + * + * Copyright 2007 - 2009 Martin Heinrich + * + * 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. + * + ******************************************************************************/ + + + +/****************************************************************************** + * Dependencies + ******************************************************************************/ + + +#include "log4qt/propertyconfigurator.h" + +#include +#include +#include "log4qt/helpers/configuratorhelper.h" +#include "log4qt/helpers/factory.h" +#include "log4qt/helpers/optionconverter.h" +#include "log4qt/helpers/properties.h" +#include "log4qt/appender.h" +#include "log4qt/layout.h" +#include "log4qt/logger.h" +#include "log4qt/logmanager.h" +#include "log4qt/loggerrepository.h" +#include "log4qt/varia/listappender.h" + + + +namespace Log4Qt +{ + + + /************************************************************************** + * Declarations + **************************************************************************/ + + + + /************************************************************************** + * C helper functions + **************************************************************************/ + + + LOG4QT_DECLARE_STATIC_LOGGER(logger, Log4Qt::PropertyConfigurator) + + + + /************************************************************************** + * Class implementation: PropertyConfigurator + **************************************************************************/ + + + bool PropertyConfigurator::doConfigure(const Properties &rProperties, + LoggerRepository *pLoggerRepository) + { + startCaptureErrors(); + configureFromProperties(rProperties, pLoggerRepository); + return stopCaptureErrors(); + } + + + bool PropertyConfigurator::doConfigure(const QString &rConfigFileName, + LoggerRepository *pLoggerRepository) + { + startCaptureErrors(); + configureFromFile(rConfigFileName, pLoggerRepository); + return stopCaptureErrors(); + } + + + bool PropertyConfigurator::doConfigure(const QSettings &rSettings, + LoggerRepository *pLoggerRepository) + { + startCaptureErrors(); + configureFromSettings(rSettings, pLoggerRepository); + return stopCaptureErrors(); + } + + + bool PropertyConfigurator::configure(const Properties &rProperties) + { + PropertyConfigurator configurator; + return configurator.doConfigure(rProperties); + } + + + bool PropertyConfigurator::configure(const QString &rConfigFilename) + { + PropertyConfigurator configurator; + return configurator.doConfigure(rConfigFilename); + } + + + bool PropertyConfigurator::configure(const QSettings &rSettings) + { + PropertyConfigurator configurator; + return configurator.doConfigure(rSettings); + } + + + bool PropertyConfigurator::configureAndWatch(const QString &rConfigFileName) + { + // Stop an existing watch to avoid a possible concurrent configuration + ConfiguratorHelper::setConfigurationFile(); + if (rConfigFileName.isEmpty()) + return true; + + PropertyConfigurator configurator; + bool result = configurator.doConfigure(rConfigFileName); + ConfiguratorHelper::setConfigurationFile(rConfigFileName, configure); + return result; + } + + + void PropertyConfigurator::configureFromFile(const QString &rConfigFileName, + LoggerRepository *pLoggerRepository) + { + QFile file(rConfigFileName); + if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) + { + LogError e = LOG4QT_ERROR(QT_TR_NOOP("Unable to open property file '%1'"), + CONFIGURATOR_OPENING_FILE_ERROR, + "Log4Qt::PropertyConfigurator"); + e << rConfigFileName; + e.addCausingError(LogError(file.errorString(), file.error())); + logger()->error(e); + return; + } + Properties properties; + properties.load(&file); + if (file.error()) + { + LogError e = LOG4QT_ERROR(QT_TR_NOOP("Unable to read property file '%1'"), + CONFIGURATOR_READING_FILE_ERROR, + "Log4Qt::PropertyConfigurator"); + e << rConfigFileName; + e.addCausingError(LogError(file.errorString(), file.error())); + logger()->error(e); + return; + } + configureFromProperties(properties, pLoggerRepository); + } + + + void PropertyConfigurator::configureFromProperties(const Properties &rProperties, + LoggerRepository *pLoggerRepository) + { + if (!pLoggerRepository) + pLoggerRepository = LogManager::loggerRepository(); + + configureGlobalSettings(rProperties, pLoggerRepository); + configureRootLogger(rProperties, pLoggerRepository); + configureNonRootElements(rProperties, pLoggerRepository); + mAppenderRegistry.clear(); + } + + + void PropertyConfigurator::configureFromSettings(const QSettings &rSettings, + LoggerRepository *pLoggerRepository) + { + Properties properties; + properties.load(rSettings); + configureFromProperties(properties, pLoggerRepository); + } + + + void PropertyConfigurator::configureGlobalSettings(const Properties &rProperties, + LoggerRepository *pLoggerRepository) const + { + Q_ASSERT_X(pLoggerRepository, "PropertyConfigurator::configureGlobalSettings()", "pLoggerRepository must not be null."); + + const QLatin1String key_reset("log4j.reset"); + const QLatin1String key_debug("log4j.Debug"); + const QLatin1String key_config_debug("log4j.configDebug"); + const QLatin1String key_threshold("log4j.threshold"); + const QLatin1String key_handle_qt_messages("log4j.handleQtMessages"); + + // Test each global setting and set it + // - Reset: log4j.reset + // - Debug: log4j.Debug, log4j.configDebug + // - Threshold: log4j.threshold + // - Handle Qt Messages: log4j.handleQtMessages + + // Reset + QString value = rProperties.property(key_reset); + if (!value.isEmpty() && OptionConverter::toBoolean(value, false)) + { + // Use LogManager and not pLoggerRepository to reset internal + // logging. + LogManager::resetConfiguration(); + logger()->debug("Reset configuration"); + } + + // Debug + value = rProperties.property(key_debug); + if (value.isNull()) + { + value = rProperties.property(key_config_debug); + if (!value.isNull()) + logger()->warn("[%1] is deprecated. Use [%2] instead.", key_config_debug, key_debug); + } + if (!value.isNull()) + { + // Don't use OptionConverter::toLevel(). Invalid level string is a valid setting + bool ok; + Level level = Level::fromString(value, &ok); + if (!ok) + level = Level::DEBUG_INT; + LogManager::logLogger()->setLevel(level); + logger()->debug("Set level for Log4Qt logging to %1", + LogManager::logLogger()->level().toString()); + } + + // Threshold + value = rProperties.property(key_threshold); + if (!value.isNull()) + { + pLoggerRepository->setThreshold(OptionConverter::toLevel(value, Level::ALL_INT)); + logger()->debug("Set threshold for LoggerRepository to %1", + pLoggerRepository->threshold().toString()); + } + + // Handle Qt messages + value = rProperties.property(key_handle_qt_messages); + if (!value.isNull()) + { + LogManager::setHandleQtMessages(OptionConverter::toBoolean(value, false)); + logger()->debug("Set handling of Qt messages LoggerRepository to %1", + QVariant(LogManager::handleQtMessages()).toString()); + } + } + + + void PropertyConfigurator::configureNonRootElements(const Properties &rProperties, + LoggerRepository *pLoggerRepository) + { + Q_ASSERT_X(pLoggerRepository, "PropertyConfigurator::configureNonRootElements()", "pLoggerRepository must not be null."); + + const QString logger_prefix = QLatin1String("log4j.logger."); + const QString category_prefix = QLatin1String("log4j.category."); + + // Iterate through all entries: + // - Test for the logger/category prefix + // - Convert JAVA class names to C++ ones + // - Parse logger data (Level, Appender) + // - Parse logger additivity + + QStringList keys = rProperties.propertyNames(); + QString key; + Q_FOREACH(key, keys) + { + QString java_name; + if (key.startsWith(logger_prefix)) + java_name = key.mid(logger_prefix.length()); + else if (key.startsWith(category_prefix)) + java_name = key.mid(category_prefix.length()); + QString cpp_name = OptionConverter::classNameJavaToCpp(java_name); + if (!java_name.isEmpty()) + { + Logger *p_logger = pLoggerRepository->logger(cpp_name); + QString value = OptionConverter::findAndSubst(rProperties, key); + parseLogger(rProperties, p_logger, key, value); + parseAdditivityForLogger(rProperties, p_logger, java_name); + } + } + } + + + void PropertyConfigurator::configureRootLogger(const Properties &rProperties, + LoggerRepository *pLoggerRepository) + { + Q_ASSERT_X(pLoggerRepository, "PropertyConfigurator::configureRootLogger()", "pLoggerRepository must not be null."); + + const QLatin1String key_root_logger("log4j.rootLogger"); + const QLatin1String key_root_category("log4j.rootCategory"); + + // - Test for the logger/category prefix + // - Parse logger data for root logger + + QString key = key_root_logger; + QString value = OptionConverter::findAndSubst(rProperties, key); + if (value.isNull()) + { + key = key_root_category; + value = OptionConverter::findAndSubst(rProperties, key); + if (!value.isNull()) + logger()->warn("[%1] is deprecated. Use [%2] instead.", key_root_category, key_root_logger); + } + + if (value.isNull()) + logger()->debug("Could not find root logger information. Is this correct?"); + else + parseLogger(rProperties, pLoggerRepository->rootLogger(), key, value); + } + + + void PropertyConfigurator::parseAdditivityForLogger(const Properties &rProperties, + Logger *pLogger, + const QString &rLog4jName) const + { + Q_ASSERT_X(pLogger, "parseAdditivityForLogger()", "pLogger must not be null."); + + const QLatin1String additivity_prefix("log4j.additivity."); + + // - Lookup additivity key for logger + // - Set additivity, if specified + + QString key = additivity_prefix + rLog4jName; + QString value = OptionConverter::findAndSubst(rProperties, key); + logger()->debug("Parsing additivity for logger: key '%1', value '%2'", key, value); + if (!value.isEmpty()) + { + bool additivity = OptionConverter::toBoolean(value, true); + logger()->debug("Setting additivity for logger '%1' to '%2'", pLogger->name(), QVariant(value).toString()); + pLogger->setAdditivity(additivity); + } + } + + + LogObjectPtr PropertyConfigurator::parseAppender(const Properties &rProperties, + const QString &rName) + { + // - Test if appender has been parsed before + // - Find appender key + // - Create appender object + // - Set layout, if required by appender + // - Set properties + // - Activate options + // - Add appender to registry + + const QLatin1String appender_prefix("log4j.appender."); + + logger()->debug("Parsing appender named '%1'", rName); + + if (mAppenderRegistry.contains(rName)) + { + logger()->debug("Appender '%1' was already parsed.", rName); + return mAppenderRegistry.value(rName); + } + + QString key = appender_prefix + rName; + QString value = OptionConverter::findAndSubst(rProperties, key); + if (value.isNull()) + { + LogError e = LOG4QT_ERROR(QT_TR_NOOP("Missing appender definition for appender named '%1'"), + CONFIGURATOR_MISSING_APPENDER_ERROR, + "Log4Qt::PropertyConfigurator"); + e << rName; + logger()->error(e); + return 0; + } + LogObjectPtr p_appender = Factory::createAppender(value); + if (!p_appender) + { + LogError e = LOG4QT_ERROR(QT_TR_NOOP("Unable to create appender of class '%1' namd '%2'"), + CONFIGURATOR_UNKNOWN_APPENDER_CLASS_ERROR, + "Log4Qt::PropertyConfigurator"); + e << value << rName; + logger()->error(e); + return 0; + } + p_appender->setName(rName); + + if (p_appender->requiresLayout()) + { + LogObjectPtr p_layout = parseLayout(rProperties, key); + if (p_layout) + p_appender->setLayout(p_layout); + else + return 0; + } + + QStringList exclusions; + exclusions << QLatin1String("layout"); + setProperties(rProperties, key + QLatin1String("."), exclusions, p_appender); + AppenderSkeleton *p_appenderskeleton = qobject_cast(p_appender); + if (p_appenderskeleton) + p_appenderskeleton->activateOptions(); + + mAppenderRegistry.insert(rName, p_appender); + return p_appender; + } + + + LogObjectPtr PropertyConfigurator::parseLayout(const Properties &rProperties, + const QString &rAppenderKey) + { + Q_ASSERT_X(!rAppenderKey.isEmpty(), "PropertyConfigurator::parseLayout()", "rAppenderKey must not be empty."); + + // - Find layout key + // - Create layput object + // - Set properties + // - Activate options + + const QLatin1String layout_suffix(".layout"); + + logger()->debug("Parsing layout for appender named '%1'", rAppenderKey); + + QString key = rAppenderKey + layout_suffix; + QString value = OptionConverter::findAndSubst(rProperties, key); + if (value.isNull()) + { + LogError e = LOG4QT_ERROR(QT_TR_NOOP("Missing layout definition for appender '%1'"), + CONFIGURATOR_MISSING_LAYOUT_ERROR, + "Log4Qt::PropertyConfigurator"); + e << rAppenderKey; + logger()->error(e); + return 0; + } + LogObjectPtr p_layout = Factory::createLayout(value); + if (!p_layout) + { + LogError e = LOG4QT_ERROR(QT_TR_NOOP("Unable to create layoput of class '%1' requested by appender '%2'"), + CONFIGURATOR_UNKNOWN_LAYOUT_CLASS_ERROR, + "Log4Qt::PropertyConfigurator"); + e << value << rAppenderKey; + logger()->error(e); + return 0; + } + + QStringList exclusions; + setProperties(rProperties, key + QLatin1String("."), QStringList(), p_layout); + p_layout->activateOptions(); + + return p_layout; + } + + + void PropertyConfigurator::parseLogger(const Properties &rProperties, + Logger *pLogger, + const QString &rKey, + const QString &rValue) + { + Q_ASSERT_X(pLogger, "PropertyConfigurator::parseLogger()", "pLogger must not be null."); + Q_ASSERT_X(!rKey.isEmpty(), "PropertyConfigurator::parseLogger()", "rKey must not be empty."); + + const QLatin1String keyword_inherited("INHERITED"); + + // - Split value on comma + // - If level value, is specified + // - Test for NULL and INHERITED + // - Ensure root logger is not set to NULL + // - Set level + // - For each entry + // - Create Appender + + logger()->debug("Parsing logger: key '%1', value '%2'", rKey, rValue); + QStringList appenders = rValue.split(QLatin1Char(',')); + QStringListIterator i (appenders); + + // First entry is the level. There will be always one entry, even if the rValue is + // empty or does not contain a comma. + QString value = i.next().trimmed(); + if (!value.isEmpty()) + { + Level level; + if (value.compare(keyword_inherited,Qt::CaseInsensitive) == 0) + level = Level::NULL_INT; + else + level = OptionConverter::toLevel(value, Level::DEBUG_INT); + if (level == Level::NULL_INT && pLogger->name() == QString()) + logger()->warn("The root logger level cannot be set to NULL."); + else + { + pLogger->setLevel(level); + logger()->debug("Set level for logger '%1' to '%2'", + pLogger->name(), pLogger->level().toString()); + } + } + + pLogger->removeAllAppenders(); + while(i.hasNext()) + { + value = i.next().trimmed(); + if(value.isEmpty()) + continue; + LogObjectPtr p_appender = parseAppender(rProperties, value); + if (p_appender) + pLogger->addAppender(p_appender); + } + } + + + void PropertyConfigurator::setProperties(const Properties &rProperties, + const QString &rPrefix, + const QStringList &rExclusions, + QObject *pObject) + { + Q_ASSERT_X(!rPrefix.isEmpty(), "PropertyConfigurator::setProperties()", "rPrefix must not be empty."); + Q_ASSERT_X(pObject, "PropertyConfigurator::setProperties()", "pObject must not be null."); + + // Iterate through all entries: + // - Test for prefix to determine, if setting is for object + // - Skip empty property name + // - Skip property names in exclusion list + // - Set property on object + + logger()->debug("Setting properties for object of class '%1' from keys starting with '%2'", + QLatin1String(pObject->metaObject()->className()), + rPrefix); + + QStringList keys = rProperties.propertyNames(); + QString key; + Q_FOREACH(key, keys) + { + if (!key.startsWith(rPrefix)) + continue; + QString property = key.mid(rPrefix.length()); + if (property.isEmpty()) + continue; + QStringList split_property = property.split(QLatin1Char('.')); + if (rExclusions.contains(split_property.at(0), Qt::CaseInsensitive)) + continue; + QString value = OptionConverter::findAndSubst(rProperties, key); + Factory::setObjectProperty(pObject, property, value); + } + } + + + void PropertyConfigurator::startCaptureErrors() + { + Q_ASSERT_X(!mpConfigureErrors, "PropertyConfigurator::startCaptureErrors()", "mpConfigureErrors must be empty."); + + mpConfigureErrors = new ListAppender; + mpConfigureErrors->setName(QLatin1String("PropertyConfigurator")); + mpConfigureErrors->setConfiguratorList(true); + mpConfigureErrors->setThreshold(Level::ERROR_INT); + LogManager::logLogger()->addAppender(mpConfigureErrors); + } + + + bool PropertyConfigurator::stopCaptureErrors() + { + Q_ASSERT_X(mpConfigureErrors, "PropertyConfigurator::stopCaptureErrors()", "mpConfigureErrors must not be empty."); + + LogManager::logLogger()->removeAppender(mpConfigureErrors); + ConfiguratorHelper::setConfigureError(mpConfigureErrors->list()); + bool result = (mpConfigureErrors->list().count() == 0); + mpConfigureErrors = 0; + return result; + } + + + + /************************************************************************** + * Implementation: Operators, Helper + **************************************************************************/ + + +#ifndef QT_NO_DEBUG_STREAM + QDebug operator<<(QDebug debug, + const PropertyConfigurator &rPropertyConfigurator) + { + Q_UNUSED(rPropertyConfigurator); + debug.nospace() << "PropertyConfigurator(" + << ")"; + return debug.space(); + } +#endif + + + +} // namespace Logging diff --git a/src/log4qt/src/log4qt/propertyconfigurator.h b/src/log4qt/src/log4qt/propertyconfigurator.h new file mode 100644 index 0000000..ddf45e5 --- /dev/null +++ b/src/log4qt/src/log4qt/propertyconfigurator.h @@ -0,0 +1,194 @@ +/****************************************************************************** + * + * package: Logging + * file: propertyconfigurator.h + * created: September 2007 + * author: Martin Heinrich + * + * + * Copyright 2007 Martin Heinrich + * + * 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. + * + ******************************************************************************/ + +#ifndef LOG4QT_PROPERTYCONFIGURATOR_H +#define LOG4QT_PROPERTYCONFIGURATOR_H + + +/****************************************************************************** + * Dependencies + ******************************************************************************/ + + +#include +#include "log4qt/helpers/logobjectptr.h" +#include "log4qt/log4qt.h" + + +/****************************************************************************** + * Declarations + ******************************************************************************/ + +class QSettings; + +namespace Log4Qt +{ + + class Appender; + class Layout; + class ListAppender; + class Logger; + class Properties; + class LoggerRepository; + + /*! + * \brief The class PropertyConfigurator allows the configuration of the + * package from a JAVA properties file. + * + * \note All the functions declared in this class are thread-safe. + */ + class PropertyConfigurator + { + public: + PropertyConfigurator(); + // virtual ~PropertyConfigurator(); // Use compiler default + private: + PropertyConfigurator(const PropertyConfigurator &rOther); // Not implemented + PropertyConfigurator &operator=(const PropertyConfigurator &rOther); // Not implemented + + public: + /*! + * \sa ConfiguratorHelper::configureError() + */ + bool doConfigure(const Properties &rProperties, + LoggerRepository *pLoggerRepository = 0); + + /*! + * \sa ConfiguratorHelper::configureError() + */ + bool doConfigure(const QString &rConfigFileName, + LoggerRepository *pLoggerRepository = 0); + + /*! + * Reads the configuration data from the QSettings object + * \a rSettings. + * + * \sa \ref Properties::load(const QSettings &) "Properties::load()", + * ConfiguratorHelper::configureError() + */ + bool doConfigure(const QSettings &rSettings, + LoggerRepository *pLoggerRepository = 0); + + // JAVA: void doConfigure(const QUrl &rUrl, LoggerRepository *pLoggerRepository); + + /*! + * \sa ConfiguratorHelper::configureError() + */ + static bool configure(const Properties &rProperties); + + /*! + * \sa ConfiguratorHelper::configureError() + */ + static bool configure(const QString &rConfigFilename); + + /*! + * Reads the configuration data from the QSettings object + * \a rSettings. + * + * \sa \ref doConfigure(const QSettings &, LoggerRepository *) "doConfigure()", + * \ref Properties::load(const QSettings &) "Properties::load()", + * ConfiguratorHelper::configureError() + */ + static bool configure(const QSettings &rSettings); + + // JAVA: static void configure(const QUrl &rUrl); + + /*! + * \sa ConfiguratorHelper::configureError(), + * ConfiguratorHelper::configurationFile() + */ + static bool configureAndWatch(const QString &rConfigFilename); + + private: + void configureFromFile(const QString &rConfigFileName, + LoggerRepository *pLoggerRepository); + void configureFromProperties(const Properties &rProperties, + LoggerRepository *pLoggerRepository); + void configureFromSettings(const QSettings &rSettings, + LoggerRepository *pLoggerRepository); + void configureGlobalSettings(const Properties &rProperties, + LoggerRepository *pLoggerRepository) const; + void configureNonRootElements(const Properties &rProperties, + LoggerRepository *pLoggerRepository); + void configureRootLogger(const Properties &rProperties, + LoggerRepository *pLoggerRepository); + void parseAdditivityForLogger(const Properties &rProperties, + Logger *pLogger, + const QString &rLog4jName) const; + LogObjectPtr parseAppender(const Properties &rProperties, + const QString &rName); + LogObjectPtr parseLayout(const Properties &rProperties, + const QString &rAppenderName); + void parseLogger(const Properties &rProperties, + Logger *pLogger, + const QString &rKey, + const QString &rValue); + void setProperties(const Properties &rProperties, + const QString &rPrefix, + const QStringList &rExclusions, + QObject *pObject); + void startCaptureErrors(); + bool stopCaptureErrors(); + + private: + LogObjectPtr mpConfigureErrors; + QHash< QString, LogObjectPtr > mAppenderRegistry; + }; + + /************************************************************************** + * Operators, Helper + **************************************************************************/ + +#ifndef QT_NO_DEBUG_STREAM + /*! + * \relates PropertyConfigurator + * + * Writes all object member variables to the given debug stream \a debug + * and returns the stream. + * + * + * %PropertyConfigurator() + * + * \sa QDebug + */ + QDebug operator<<(QDebug debug, + const PropertyConfigurator &rPropertyConfigurator); +#endif + + + /************************************************************************** + * Inline + **************************************************************************/ + + inline PropertyConfigurator::PropertyConfigurator() + {} + + +} // namspace Logging + + +// Q_DECLARE_TYPEINFO(Log4Qt::PropertyConfigurator, Q_COMPLEX_TYPE); // Use default + + +#endif // LOG4QT_PROPERTYCONFIGURATOR_H diff --git a/src/log4qt/src/log4qt/rollingfileappender.cpp b/src/log4qt/src/log4qt/rollingfileappender.cpp new file mode 100644 index 0000000..44f7bbe --- /dev/null +++ b/src/log4qt/src/log4qt/rollingfileappender.cpp @@ -0,0 +1,191 @@ +/****************************************************************************** + * + * package: Log4Qt + * file: rollingfileappender.cpp + * created: September 2007 + * author: Martin Heinrich + * + * + * Copyright 2007 Martin Heinrich + * + * 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. + * + ******************************************************************************/ + + + +/****************************************************************************** + * Dependencies + ******************************************************************************/ + + +#include "log4qt/rollingfileappender.h" + +#include +#include +#include +#include "log4qt/helpers/optionconverter.h" +#include "log4qt/layout.h" +#include "log4qt/loggingevent.h" + + + +namespace Log4Qt +{ + + + /************************************************************************ + Declarations + *************************************************************************/ + + + + /************************************************************************ + C helper functions + *************************************************************************/ + + + + /************************************************************************ + Class implementation: RollingFileAppender + *************************************************************************/ + + + RollingFileAppender::RollingFileAppender(QObject *pParent) : + FileAppender(pParent), + mMaxBackupIndex(1), + mMaximumFileSize(10*1024*1024) + { + } + + + RollingFileAppender::RollingFileAppender(Layout *pLayout, + const QString &rFileName, + QObject *pParent) : + FileAppender(pLayout, rFileName, pParent), + mMaxBackupIndex(1), + mMaximumFileSize(10*1024*1024) + { + } + + + RollingFileAppender::RollingFileAppender(Layout *pLayout, + const QString &rFileName, + bool append, + QObject *pParent) : + FileAppender(pLayout, rFileName, append, pParent), + mMaxBackupIndex(1), + mMaximumFileSize(10*1024*1024) + { + } + + + RollingFileAppender::~RollingFileAppender() + { + close(); + } + + + void RollingFileAppender::setMaxFileSize(const QString &rMaxFileSize) + { + bool ok; + qint64 max_file_size = OptionConverter::toFileSize(rMaxFileSize, &ok); + if (ok) + setMaximumFileSize(max_file_size); + } + + + void RollingFileAppender::append(const LoggingEvent &rEvent) + { + // Q_ASSERT_X(, "RollingFileAppender::append()", "Lock must be held by caller") + + FileAppender::append(rEvent); + if (writer()->device()->size() > this->mMaximumFileSize) + rollOver(); + } + + + void RollingFileAppender::rollOver() + { + // Q_ASSERT_X(, "RollingFileAppender::rollOver()", "Lock must be held by caller") + + logger()->debug("Rolling over with maxBackupIndex = %1", mMaxBackupIndex); + + closeFile(); + + QFile f; + f.setFileName(file() + QLatin1Char('.') + QString::number(mMaxBackupIndex)); + if (f.exists() && !removeFile(f)) + return; + + QString target_file_name; + int i; + for (i = mMaxBackupIndex - 1; i >=1; i--) + { + f.setFileName(file() + QLatin1Char('.') + QString::number(i)); + if (f.exists()) + { + target_file_name = file() + QLatin1Char('.') + QString::number(i + 1); + if (!renameFile(f, target_file_name)) + return; + } + } + + f.setFileName(file()); + target_file_name = file() + QLatin1String(".1"); + if (!renameFile(f, target_file_name)) + return; + + openFile(); + } + + +#ifndef QT_NO_DEBUG_STREAM + QDebug RollingFileAppender::debug(QDebug &rDebug) const + { + QString layout_name; + if (layout()) + layout_name = layout()->name(); + QString codec_name; + if (encoding()) + codec_name = QLatin1String(encoding()->name()); + + rDebug.nospace() << "RollingFileAppender(" + << "name:" << name() << " " + << "appendfile:" << appendFile() << " " + << "bufferedio:" << bufferedIo() << " " + << "encoding:" << codec_name << " " + << "file:" << file() << " " + << "filter:" << firstFilter() << " " + << "immediateflush:" << immediateFlush() << " " + << "isactive:" << isActive() << " " + << "isclosed:" << isClosed() << " " + << "layout:" << layout_name << " " + << "maxbackupindex:" << maxBackupIndex() << " " + << "maximumfilesize:" << maximumFileSize() << " " + << "referencecount:" << referenceCount() << " " + << "threshold:" << threshold().toString() << " " + << "writer:" << writer() + << ")"; + return rDebug.space(); + } +#endif // QT_NO_DEBUG_STREAM + + + + /************************************************************************** + * Implementation: Operators, Helper + **************************************************************************/ + + +} // namespace Log4Qt diff --git a/src/log4qt/src/log4qt/rollingfileappender.h b/src/log4qt/src/log4qt/rollingfileappender.h new file mode 100644 index 0000000..0f07ad9 --- /dev/null +++ b/src/log4qt/src/log4qt/rollingfileappender.h @@ -0,0 +1,164 @@ +/****************************************************************************** + * + * package: Log4Qt + * file: rollingfileappender.h + * created: September 2007 + * author: Martin Heinrich + * + * + * Copyright 2007 Martin Heinrich + * + * 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. + * + ******************************************************************************/ + +#ifndef LOG4QT_ROLINGFILEAPPENDER_H +#define LOG4QT_ROLINGFILEAPPENDER_H + + +/****************************************************************************** + * Dependencies + ******************************************************************************/ + +#include "log4qt/fileappender.h" + + +/****************************************************************************** + * Declarations + ******************************************************************************/ + +namespace Log4Qt +{ + + /*! + * \brief The class RollingFileAppender extends FileAppender to backup + * the log files when they reach a certain size. + * + * \note All the functions declared in this class are thread-safe. + * + * \note The ownership and lifetime of objects of this class are managed. + * See \ref Ownership "Object ownership" for more details. + */ + class RollingFileAppender : public FileAppender + { + Q_OBJECT + + /*! + * The property holds the maximum backup count used by the appender. + * + * The default is 1. + * + * \sa maxBackupIndex(), setMaxBackupIndex() + */ + Q_PROPERTY(int maxBackupIndex READ maxBackupIndex WRITE setMaxBackupIndex) + + /*! + * The property holds the maximum file size used by the appender. + * + * The default is 10 MB (10 * 1024 * 1024). + * + * \sa maximumFileSize(), setMaximumFileSize() + */ + Q_PROPERTY(qint64 maximumFileSize READ maximumFileSize WRITE setMaximumFileSize) + + /*! + * The property sets the maximum file size from a string value. + * + * \sa setMaxFileSize(), maximumFileSize() + */ + Q_PROPERTY(QString maxFileSize WRITE setMaxFileSize) + + public: + RollingFileAppender(QObject *pParent = 0); + RollingFileAppender(Layout *pLayout, + const QString &rFileName, + QObject *pParent = 0); + RollingFileAppender(Layout *pLayout, + const QString &rFileName, + bool append, + QObject *pParent = 0); + virtual ~RollingFileAppender(); + private: + RollingFileAppender(const RollingFileAppender &rOther); // Not implemented + RollingFileAppender &operator=(const RollingFileAppender &rOther); // Not implemented + + public: + int maxBackupIndex() const; + qint64 maximumFileSize() const; + void setMaxBackupIndex(int maxBackupIndex); + void setMaximumFileSize(qint64 maximumFileSize); + void setMaxFileSize(const QString &rMaxFileSize); + + protected: + virtual void append(const LoggingEvent &rEvent); + +#ifndef QT_NO_DEBUG_STREAM + /*! + * Writes all object member variables to the given debug stream + * \a rDebug and returns the stream. + * + * + * %RollingFileAppender(name:"RFA" appendfile:false bufferedio:true + * encoding:"" file:"/log.txt" filter: 0x0 + * immediateflush:true isactive:true + * isclosed:false layout:"TTCC" maxbackupindex:2 + * maximumfilesize:40 referencecount:1 + * threshold:"NULL" writer:0x4175af8) + * + * \sa QDebug, operator<<(QDebug debug, const LogObject &rLogObject) + */ + virtual QDebug debug(QDebug &rDebug) const; +#endif // QT_NO_DEBUG_STREAM + + private: + void rollOver(); + + private: + int mMaxBackupIndex; + qint64 mMaximumFileSize; + }; + + + /************************************************************************** + * Operators, Helper + **************************************************************************/ + + + /************************************************************************** + * Inline + **************************************************************************/ + + inline int RollingFileAppender::maxBackupIndex() const + { QMutexLocker locker(&mObjectGuard); + return mMaxBackupIndex; } + + inline qint64 RollingFileAppender::maximumFileSize() const + { QMutexLocker locker(&mObjectGuard); + return mMaximumFileSize; } + + inline void RollingFileAppender::setMaxBackupIndex(int maxBackupIndex) + { QMutexLocker locker(&mObjectGuard); + mMaxBackupIndex = maxBackupIndex; } + + inline void RollingFileAppender::setMaximumFileSize(qint64 maximumFileSize) + { QMutexLocker locker(&mObjectGuard); + mMaximumFileSize = maximumFileSize; } + + +} // namespace Log4Qt + + +// Q_DECLARE_TYPEINFO(Log4Qt::RollingFileAppender, Q_COMPLEX_TYPE); // Use default + + +#endif // LOG4QT_ROLINGFILEAPPENDER_H diff --git a/src/log4qt/src/log4qt/simplelayout.cpp b/src/log4qt/src/log4qt/simplelayout.cpp new file mode 100644 index 0000000..a7d5234 --- /dev/null +++ b/src/log4qt/src/log4qt/simplelayout.cpp @@ -0,0 +1,84 @@ +/****************************************************************************** + * + * package: Log4Qt + * file: simplelayout.cpp + * created: September 2007 + * author: Martin Heinrich + * + * + * Copyright 2007 Martin Heinrich + * + * 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. + * + ******************************************************************************/ + + + +/****************************************************************************** + * Dependencies + ******************************************************************************/ + + +#include "log4qt/simplelayout.h" + +#include +#include "log4qt/loggingevent.h" + + + +namespace Log4Qt +{ + + + /************************************************************************** + * Declarations + **************************************************************************/ + + + + /************************************************************************** + * C helper functions + **************************************************************************/ + + + + /************************************************************************** + * Class implementation: SimpleLayout + **************************************************************************/ + + + QString SimpleLayout::format(const LoggingEvent &rEvent) + { + return rEvent.level().toString() + QLatin1String(" - ") + rEvent.message() + Layout::endOfLine(); + } + + +#ifndef QT_NO_DEBUG_STREAM + QDebug SimpleLayout::debug(QDebug &rDebug) const + { + rDebug.nospace() << "SimpleLayout(" + << "name:" << name() << " " + << "referencecount:" << referenceCount() + << ")"; + return rDebug.space(); + } +#endif // QT_NO_DEBUG_STREAM + + + + /************************************************************************** + * Implementation: Operators, Helper + **************************************************************************/ + + +} // namespace Log4Qt diff --git a/src/log4qt/src/log4qt/simplelayout.h b/src/log4qt/src/log4qt/simplelayout.h new file mode 100644 index 0000000..5ebe558 --- /dev/null +++ b/src/log4qt/src/log4qt/simplelayout.h @@ -0,0 +1,102 @@ +/****************************************************************************** + * + * package: Log4Qt + * file: simplelayout.h + * created: September 2007 + * author: Martin Heinrich + * + * + * Copyright 2007 Martin Heinrich + * + * 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. + * + ******************************************************************************/ + +#ifndef LOG4QT_SIMPLELAYOUT_H +#define LOG4QT_SIMPLELAYOUT_H + + +/****************************************************************************** + * Dependencies + ******************************************************************************/ + +#include "log4qt/layout.h" + + +/****************************************************************************** + * Declarations + ******************************************************************************/ + + +namespace Log4Qt +{ + + /*! + * \brief The class SimpleLayout outputs the level and message of a logging + * event. + * + * \note The ownership and lifetime of objects of this class are managed. + * See \ref Ownership "Object ownership" for more details. + */ + class SimpleLayout : public Layout + { + Q_OBJECT + + public: + SimpleLayout(QObject *pParent = 0); + // virtual ~SimpleLayout(); // Use compiler default + private: + SimpleLayout(const SimpleLayout &rOther); // Not implemented + SimpleLayout &operator=(const SimpleLayout &rOther); // Not implemented + + public: + virtual QString format(const LoggingEvent &rEvent); + + protected: + +#ifndef QT_NO_DEBUG_STREAM + /*! + * Writes all object member variables to the given debug stream + * \a rDebug and returns the stream. + * + * + * %SimpleLayout(name:"SL" referencecount:1) + * + * \sa QDebug, operator<<(QDebug debug, const LogObject &rLogObject) + */ + virtual QDebug debug(QDebug &rDebug) const; +#endif // QT_NO_DEBUG_STREAM + }; + + + /************************************************************************** + * Operators, Helper + **************************************************************************/ + + + /************************************************************************** + * Inline + **************************************************************************/ + + inline SimpleLayout::SimpleLayout(QObject *pParent) : + Layout(pParent) + {} + + +} // namespace Log4Qt + + +// Q_DECLARE_TYPEINFO(Log4Qt::SimpleLayout, Q_COMPLEX_TYPE); // Use default + + +#endif // LOG4QT_SIMPLELAYOUT_H diff --git a/src/log4qt/src/log4qt/spi/filter.cpp b/src/log4qt/src/log4qt/spi/filter.cpp new file mode 100644 index 0000000..8f2d10e --- /dev/null +++ b/src/log4qt/src/log4qt/spi/filter.cpp @@ -0,0 +1,70 @@ +/****************************************************************************** + * + * package: Log4Qt + * file: filter.cpp + * created: September 2007 + * author: Martin Heinrich + * + * + * Copyright 2007 Martin Heinrich + * + * 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. + * + ******************************************************************************/ + + + +/****************************************************************************** + * Dependencies + ******************************************************************************/ + + +#include "log4qt/spi/filter.h" + +#include + + +namespace Log4Qt +{ + + + /************************************************************************** + * Declarations + **************************************************************************/ + + + + /************************************************************************** + * C helper functions + **************************************************************************/ + + + + /************************************************************************** + * Class implementation: Filter + **************************************************************************/ + + + void Filter::setNext(Filter *pFilter) + { + mpNext = pFilter; + } + + + + /************************************************************************** + * Implementation: Operators, Helper + **************************************************************************/ + + +} // namespace Log4Qt diff --git a/src/log4qt/src/log4qt/spi/filter.h b/src/log4qt/src/log4qt/spi/filter.h new file mode 100644 index 0000000..0fd48f0 --- /dev/null +++ b/src/log4qt/src/log4qt/spi/filter.h @@ -0,0 +1,124 @@ +/****************************************************************************** + * + * package: Log4Qt + * file: filter.h + * created: September 2007 + * author: Martin Heinrich + * + * + * Copyright 2007 Martin Heinrich + * + * 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. + * + ******************************************************************************/ + +#ifndef LOG4QT_FILTER_H +#define LOG4QT_FILTER_H + + +/****************************************************************************** + * Dependencies + ******************************************************************************/ + +#include "log4qt/helpers/logobject.h" + +#include "log4qt/helpers/logobjectptr.h" +#include "log4qt/log4qt.h" + + +/****************************************************************************** + * Declarations + ******************************************************************************/ + +namespace Log4Qt +{ + + class LoggingEvent; + + /*! + * \brief The class Filter is the base class for all filters. + * + * \note The ownership and lifetime of objects of this class are managed. + * See \ref Ownership "Object ownership" for more details. + */ + class Filter : public LogObject + { + Q_OBJECT + + /*! + * The property holds the next filter of this filter. + * + * The default is 0 for no next filter. + * + * \sa next(), setNext() + */ + Q_PROPERTY(Filter* next READ next WRITE setNext) + + public: + enum Decision + { + ACCEPT, + DENY, + NEUTRAL + }; + Q_ENUMS(Decision); + + public: + Filter(QObject *pObject = 0); + // Filter(const Filter &rOther); // Use compiler default + virtual ~Filter(); + // Filter &operator=(const Filter &rOther); // Use compiler default + + Filter* next() const; + void setNext(Filter *pFilter); + + virtual void activateOptions(); + virtual Decision decide(const LoggingEvent &rEvent) const = 0; + + private: + LogObjectPtr mpNext; + }; + + + /************************************************************************** + * Operators, Helper + **************************************************************************/ + + + /************************************************************************** + * Inline + **************************************************************************/ + + inline Filter::Filter(QObject *pObject) : + LogObject(pObject), + mpNext(0) + {} + + inline Filter::~Filter() + {} + + inline Filter* Filter::next() const + { return mpNext; } + + inline void Filter::activateOptions() + {} + + +} // namespace Log4Qt + + +// Q_DECLARE_TYPEINFO(Log4Qt::Filter, Q_COMPLEX_TYPE); // Use default +Q_DECLARE_TYPEINFO(Log4Qt::LogObjectPtr, Q_MOVABLE_TYPE); + + +#endif // LOG4QT_FILTER_H diff --git a/src/log4qt/src/log4qt/ttcclayout.cpp b/src/log4qt/src/log4qt/ttcclayout.cpp new file mode 100644 index 0000000..023ba11 --- /dev/null +++ b/src/log4qt/src/log4qt/ttcclayout.cpp @@ -0,0 +1,182 @@ +/****************************************************************************** + * + * package: Log4Qt + * file: ttcclayout.cpp + * created: September 2007 + * author: Martin Heinrich + * + * + * Copyright 2007 Martin Heinrich + * + * 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. + * + ******************************************************************************/ + + + +/****************************************************************************** + * Dependencies + ******************************************************************************/ + + +#include "log4qt/ttcclayout.h" + +#include +#include +#include "log4qt/helpers/datetime.h" +#include "log4qt/helpers/patternformatter.h" +#include "log4qt/logger.h" +#include "log4qt/loggingevent.h" + + + +namespace Log4Qt +{ + + + /************************************************************************** + * Declarations + **************************************************************************/ + + + + /************************************************************************** + * C helper functions + **************************************************************************/ + + + + /************************************************************************** + * Class implementation: TTCCLayout + **************************************************************************/ + + + TTCCLayout::TTCCLayout(QObject *pParent) : + Layout(pParent), + mCategoryPrefixing(true), + mContextPrinting(true), + mDateFormat(), + mThreadPrinting(true), + mpPatternFormatter(0) + { + setDateFormat(TIME_RELATIVE); + } + + + TTCCLayout::TTCCLayout(const QString &rDateFormat, + QObject *pParent) : + Layout(pParent), + mCategoryPrefixing(true), + mContextPrinting(true), + mDateFormat(rDateFormat), + mThreadPrinting(true), + mpPatternFormatter(0) + { + } + + + TTCCLayout::TTCCLayout(DateFormat dateFormat, + QObject *pParent) : + Layout(pParent), + mCategoryPrefixing(true), + mContextPrinting(true), + mDateFormat(), + mThreadPrinting(true), + mpPatternFormatter(0) + { + setDateFormat(dateFormat); + } + + + TTCCLayout::~TTCCLayout() + { + delete mpPatternFormatter; + } + + + void TTCCLayout::setDateFormat(DateFormat dateFormat) + { + switch (dateFormat) + { + case NONE: + setDateFormat(QLatin1String("NONE")); + break; + case ISO8601: + setDateFormat(QLatin1String("ISO8601")); + break; + case TIME_ABSOLUTE: + setDateFormat(QLatin1String("TIME_ABSOLUTE")); + break; + case DATE: + setDateFormat(QLatin1String("DATE")); + break; + case TIME_RELATIVE: + setDateFormat(QLatin1String("TIME_RELATIVE")); + break; + default: + Q_ASSERT_X(false, "TTCCLayout::setDateFormat", "Unkown DateFormat"); + setDateFormat(QString()); + } + } + + + QString TTCCLayout::format(const LoggingEvent &rEvent) + { + Q_ASSERT_X(mpPatternFormatter, "TTCCLayout::format()", "mpPatternConverter must not be null"); + + return mpPatternFormatter->format(rEvent); + } + + + void TTCCLayout::updatePatternFormatter() + { + QString pattern; + + pattern += QLatin1String("%d{") + mDateFormat + QLatin1String("}"); + if (mThreadPrinting) + pattern += QLatin1String(" [%t]"); + pattern += QLatin1String(" %-5p"); + if (mCategoryPrefixing) + pattern += QLatin1String(" %c"); + if (mContextPrinting) + pattern += QLatin1String(" %x"); + pattern += QLatin1String(" - %m%n"); + + delete mpPatternFormatter; + mpPatternFormatter = new PatternFormatter(pattern); + } + + +#ifndef QT_NO_DEBUG_STREAM + QDebug TTCCLayout::debug(QDebug &rDebug) const + { + rDebug.nospace() << "TTCCLayout(" + << "name:" << name() << " " + << "categoryprefixing:" << categoryPrefixing() << " " + << "contextprinting:" << contextPrinting() << " " + << "dateformat:" << dateFormat() << " " + << "referencecount:" << referenceCount() << " " + << "threadprinting:" << threadPrinting() + << ")"; + return rDebug.space(); + } +#endif // QT_NO_DEBUG_STREAM + + + + /************************************************************************** + * Implementation: Operators, Helper + **************************************************************************/ + + +} // namespace Log4Qt diff --git a/src/log4qt/src/log4qt/ttcclayout.h b/src/log4qt/src/log4qt/ttcclayout.h new file mode 100644 index 0000000..c147b00 --- /dev/null +++ b/src/log4qt/src/log4qt/ttcclayout.h @@ -0,0 +1,235 @@ +/****************************************************************************** + * + * package: Log4Qt + * file: ttcclayout.h + * created: September 2007 + * author: Martin Heinrich + * + * + * Copyright 2007 Martin Heinrich + * + * 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. + * + ******************************************************************************/ + +#ifndef LOG4QT_TTCCLAYOUT_H +#define LOG4QT_TTCCLAYOUT_H + + +/****************************************************************************** + * Dependencies + ******************************************************************************/ + +#include "log4qt/layout.h" + + +/****************************************************************************** + * Declarations + ******************************************************************************/ + +namespace Log4Qt +{ + + class LoggingEvent; + class PatternFormatter; + + /*! + * \brief The class TTCCLayout outputs the time, thread, logger and nested + * diagnostic context information of a logging event. + * + * \note The ownership and lifetime of objects of this class are managed. + * See \ref Ownership "Object ownership" for more details. + */ + class TTCCLayout : public Layout + { + Q_OBJECT + + /*! + * The property holds if the logger name is part of the formatted output. + * + * The default value is true for including the logger name. + * + * \sa categoryPrefixing(), setCategoryPrefixing() + */ + Q_PROPERTY(bool categoryPrefixing READ categoryPrefixing WRITE setCategoryPrefixing) + + /*! + * The property holds if the nested context information is part of the + * formatted output. + * + * The default value it true for including the nested context information. + * + * \sa contextPrinting(), setContextPrinting() + */ + Q_PROPERTY(bool contextPrinting READ contextPrinting WRITE setContextPrinting) + + /*! + * The property holds the date format used by the layout. + * + * The default date format is "TIME_RELATIVE". + * + * \sa dateFormat(), setDateFormat() + */ + Q_PROPERTY(QString dateFormat READ dateFormat WRITE setDateFormat) + + /*! + * The property holds if the thread name is part of the formatted output. + * + * The default value it true for including the thread name. + * + * \sa threadPrinting(), setThreadPrinting() + */ + Q_PROPERTY(bool threadPrinting READ threadPrinting WRITE setThreadPrinting) + + public: + /*! + * The enum DateFormat defines constants for date formats. + * + * \sa setDateFormat(DateFormat), DateTime::toString() + */ + enum DateFormat + { + /*! The none date format string is "NONE". */ + NONE, + /*! + * The iso8601 date format string is "ISO8601". The date will be + * formatted as yyyy-MM-dd hh:mm:ss.zzz. + */ + ISO8601, + /*! + * The absolute date format string is "TIME_ABSOLUTE". The date will be + * formatted as HH:mm:ss.zzz. + */ + TIME_ABSOLUTE, + /*! + * The date date format string is "DATE". The date will be formatted + * as MMM YYYY HH:mm:ss.zzzz. + */ + DATE, + /*! + * The relative date format string is "TIME_RELATIVE". The date will be + * formatted as milliseconds since start of the program. + */ + TIME_RELATIVE + }; + Q_ENUMS(DateFormat) + + TTCCLayout(QObject *pParent = 0); + TTCCLayout(const QString &rDateFormat, + QObject *pParent = 0); + + /*! + * Creates a TTCCLayout with the date formar value specified by + * the \a dateFormat constant and the parent \a pParent. + */ + TTCCLayout(DateFormat dateFormat, + QObject *pParent = 0); + + virtual ~TTCCLayout(); + private: + TTCCLayout(const TTCCLayout &rOther); // Not implemented + TTCCLayout &operator=(const TTCCLayout &rOther); // Not implemented + + public: + bool categoryPrefixing() const; + bool contextPrinting() const; + QString dateFormat() const; + // JAVA: bool ignoresThrowable() const; + bool threadPrinting() const; + void setCategoryPrefixing(bool categoryPrefixing); + void setContextPrinting(bool contextPrinting); + void setDateFormat(const QString &rDateFormat); + + /*! + * Sets the date format to the value specified by the \a dateFormat + * constant. + */ + void setDateFormat(DateFormat dateFormat); + + // JAVA: setIgnoresThrowable(bool ignoresThrowable); + void setThreadPrinting(bool threadPrinting); + virtual QString format(const LoggingEvent &rEvent); + + protected: +#ifndef QT_NO_DEBUG_STREAM + /*! + * Writes all object member variables to the given debug stream + * \a rDebug and returns the stream. + * + * + * %TTCCLayout(name:"TTCC" categoryprefixing:true + * contextprinting:true dateformat:"ISO8601" + * referencecount:1 threadprinting:true) + * + * \sa QDebug, operator<<(QDebug debug, const LogObject &rLogObject) + */ + virtual QDebug debug(QDebug &rDebug) const; +#endif // QT_NO_DEBUG_STREAM + + private: + void updatePatternFormatter(); + + private: + bool mCategoryPrefixing; + bool mContextPrinting; + QString mDateFormat; + bool mThreadPrinting; + PatternFormatter *mpPatternFormatter; + }; + + + /************************************************************************** + * Operators, Helper + **************************************************************************/ + + + /************************************************************************** + * Inline + **************************************************************************/ + + inline bool TTCCLayout::categoryPrefixing() const + { return mCategoryPrefixing; } + + inline bool TTCCLayout::contextPrinting() const + { return mContextPrinting; } + + inline QString TTCCLayout::dateFormat() const + { return mDateFormat; } + + inline bool TTCCLayout::threadPrinting() const + { return mThreadPrinting; } + + inline void TTCCLayout::setCategoryPrefixing(bool categoryPrefixing) + { mCategoryPrefixing = categoryPrefixing; + updatePatternFormatter(); } + + inline void TTCCLayout::setContextPrinting(bool contextPrinting) + { mContextPrinting = contextPrinting; + updatePatternFormatter(); } + + inline void TTCCLayout::setDateFormat(const QString &rDateFormat) + { mDateFormat = rDateFormat; + updatePatternFormatter(); } + + inline void TTCCLayout::setThreadPrinting(bool threadPrinting) + { mThreadPrinting = threadPrinting; + updatePatternFormatter(); } + + +} // namespace Log4Qt + + +// Q_DECLARE_TYPEINFO(Log4Qt::TTCCLayout, Q_COMPLEX_TYPE); // Use default + + +#endif // LOG4QT_TTCCLAYOUT_H diff --git a/src/log4qt/src/log4qt/varia/debugappender.cpp b/src/log4qt/src/log4qt/varia/debugappender.cpp new file mode 100644 index 0000000..d4d0bd2 --- /dev/null +++ b/src/log4qt/src/log4qt/varia/debugappender.cpp @@ -0,0 +1,127 @@ +/****************************************************************************** + * + * package: Log4Qt + * file: debugappender.cpp + * created: September 2007 + * author: Martin Heinrich + * + * + * Copyright 2007 Martin Heinrich + * + * 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. + * + ******************************************************************************/ + + + +/****************************************************************************** + * Dependencies + ******************************************************************************/ + + +#include "log4qt/varia/debugappender.h" + +#include +#include +#include "log4qt/layout.h" +#include "log4qt/loggingevent.h" +#if defined(Q_WS_WIN) || defined(Q_OS_WIN32) + #include +#endif + +namespace Log4Qt +{ + + + /************************************************************************** + * Declarations + **************************************************************************/ + + + + /************************************************************************** + * C helper functions + **************************************************************************/ + + + + /************************************************************************** + * Class implementation: DebugAppender + **************************************************************************/ + + + DebugAppender::DebugAppender(Layout *pLayout, + QObject *pParent) : + AppenderSkeleton(pParent) + { + setLayout(pLayout); + } + + + bool DebugAppender::requiresLayout() const + { + return true; + } + + + void DebugAppender::append(const LoggingEvent &rEvent) + { + // Q_ASSERT_X(, "DebugAppender::append()", "Lock must be held by caller"); + Q_ASSERT_X(layout(), "DebugAppender::append()", "Layout must not be null"); + + QString message(layout()->format(rEvent)); +#if defined(Q_OS_WIN32) || defined(Q_WS_WIN) + #if (QT_VERSION < 0x050000) + QT_WA({ + OutputDebugStringW(reinterpret_cast(message.utf16())); + }, { + OutputDebugStringA(message.toLocal8Bit().data()); + }); + #else + OutputDebugStringW(reinterpret_cast(message.utf16())); + #endif +#else + fprintf(stderr, "%s", message.toLocal8Bit().data()); + fflush(stderr); +#endif + } + + + + /************************************************************************** + * Implementation: Operators, Helper + **************************************************************************/ + + +#ifndef QT_NO_DEBUG_STREAM + QDebug DebugAppender::debug(QDebug &rDebug) const + { + QString layout_name; + if (layout()) + layout_name = layout()->name(); + + rDebug.nospace() << "DebugAppender(" + << "name:" << name() << " " + << "filter:" << firstFilter() << " " + << "isactive:" << isActive() << " " + << "isclosed:" << isClosed() << " " + << "layout:" << layout_name << " " + << "referencecount:" << referenceCount() << " " + << "threshold:" << threshold().toString() + << ")"; + return rDebug.space(); + } +#endif // QT_NO_DEBUG_STREAM + + +} // namspace Log4Qt diff --git a/src/log4qt/src/log4qt/varia/debugappender.h b/src/log4qt/src/log4qt/varia/debugappender.h new file mode 100644 index 0000000..fc2b7f0 --- /dev/null +++ b/src/log4qt/src/log4qt/varia/debugappender.h @@ -0,0 +1,133 @@ +/****************************************************************************** + * + * package: Log4Qt + * file: debugappender.h + * created: September 2007 + * author: Martin Heinrich + * + * + * Copyright 2007 Martin Heinrich + * + * 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. + * + ******************************************************************************/ + +#ifndef LOG4QT_DEBUGAPPENDER_H +#define LOG4QT_DEBUGAPPENDER_H + + +/****************************************************************************** + * Dependencies + ******************************************************************************/ + +#include "log4qt/appenderskeleton.h" + + +/****************************************************************************** + * Declarations + ******************************************************************************/ + +namespace Log4Qt +{ + + /*! + * \brief The class DebugAppender appends logging events to the platform + * specific debug output. + * + * A DebugAppender appends to the Debugger on Windows and to stderr on all + * other systems. + * + * \note All the functions declared in this class are thread-safe. + * + * \note The ownership and lifetime of objects of this class are managed. + * See \ref Ownership "Object ownership" for more details. + */ + class DebugAppender : public AppenderSkeleton + { + Q_OBJECT + + public: + /*! + * Creates a DebugAppender. + */ + DebugAppender(QObject *pParent = 0); + + /*! + * Creates a DebugAppender with the specified layout \a pLayout + */ + DebugAppender(Layout *pLayout, + QObject *pParent = 0); + + // virtual ~DebugAppender(); // Use compiler default + private: + DebugAppender(const DebugAppender &rOther); // Not implemented + DebugAppender &operator=(const DebugAppender &rOther); // Not implemented + + public: + /*! + * The DebugAppended requires a layout. The function returns true. + * + * \sa setLayout() + */ + virtual bool requiresLayout() const; + + protected: + /*! + * Appends the specified logging event \a rEvent to the debug output. + * The output is formatted using the appender's layout. + * + * The method is called by the AppenderSkeleton::doAppend() after it + * the entry conditions have been tested and it has been found that the + * logging event needs to be appended. + * + * \sa setLayout(), AppenderSkeleton::doAppend(), checkEntryConditions() + */ + virtual void append(const LoggingEvent &rEvent); + +#ifndef QT_NO_DEBUG_STREAM + /*! + * Writes all object member variables to the given debug stream \a rDebug + * and returns the stream. + * + * + * %DebugAppender(name:"DA" filter:0x3bee6b8 isactive:true isclosed:false + * layout:"SL" referencecount:1 threshold:"NULL") + * + * \sa QDebug, operator<<(QDebug debug, const LogObject &rLogObject) + */ + virtual QDebug debug(QDebug &rDebug) const; +#endif // QT_NO_DEBUG_STREAM + }; + + + /************************************************************************** + * Operators, Helper + **************************************************************************/ + + + /************************************************************************** + * Inline + **************************************************************************/ + + inline DebugAppender::DebugAppender(QObject *pParent) : + AppenderSkeleton(pParent) + {} + + +} // namespace Log4Qt + + +// Q_DECLARE_TYPEINFO(Log4Qt::DebugAppender, Q_COMPLEX_TYPE); // Use default + + +#endif // LOG4QT_DEBUGAPPENDER_H diff --git a/src/log4qt/src/log4qt/varia/denyallfilter.cpp b/src/log4qt/src/log4qt/varia/denyallfilter.cpp new file mode 100644 index 0000000..31d8f64 --- /dev/null +++ b/src/log4qt/src/log4qt/varia/denyallfilter.cpp @@ -0,0 +1,77 @@ +/****************************************************************************** + * + * package: Log4Qt + * file: denyallfilter.cpp + * created: September 2007 + * author: Martin Heinrich + * + * + * Copyright 2007 Martin Heinrich + * + * 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. + * + ******************************************************************************/ + + + +/****************************************************************************** + * Dependencies + ******************************************************************************/ + + +#include "log4qt/varia/denyallfilter.h" + +#include + + +namespace Log4Qt +{ + + + /************************************************************************** + * Declarations + **************************************************************************/ + + + + /************************************************************************** + * C helper functions + **************************************************************************/ + + + + /************************************************************************** + * Class implementation: Filter + **************************************************************************/ + + +#ifndef QT_NO_DEBUG_STREAM + QDebug DenyAllFilter::debug(QDebug &rDebug) const + { + rDebug.nospace() << "DenyAllFilter(" + << "next:" << next() + << "referencecount:" << referenceCount() << " " + << ")"; + return rDebug.space(); + } +#endif // QT_NO_DEBUG_STREAM + + + + /************************************************************************** + * Implementation: Operators, Helper + **************************************************************************/ + + + +} // namespace Log4Qt diff --git a/src/log4qt/src/log4qt/varia/denyallfilter.h b/src/log4qt/src/log4qt/varia/denyallfilter.h new file mode 100644 index 0000000..e67ffaa --- /dev/null +++ b/src/log4qt/src/log4qt/varia/denyallfilter.h @@ -0,0 +1,105 @@ +/****************************************************************************** + * + * package: Log4Qt + * file: denyallfilter.h + * created: September 2007 + * author: Martin Heinrich + * + * + * changes Feb 2009, Martin Heinrich + * - Fixed a compile error on VS 2008 by using Q_UNUSED(&rEvent) + * instead of Q_UNUSED(rEvent) + * + * + * Copyright 2007 - 2009 Martin Heinrich + * + * 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. + * + ******************************************************************************/ + +#ifndef LOG4QT_DENYALLFILTER_H +#define LOG4QT_DENYALLFILTER_H + + +/****************************************************************************** + * Dependencies + ******************************************************************************/ + +#include "log4qt/spi/filter.h" + + +/****************************************************************************** + * Declarations + ******************************************************************************/ + +namespace Log4Qt +{ + + /*! + * \brief The class DenyAllFilter drops all logging events + * + * \note The ownership and lifetime of objects of this class are managed. + * See \ref Ownership "Object ownership" for more details. + */ + class DenyAllFilter : public Filter + { + Q_OBJECT + + public: + DenyAllFilter(QObject *pParent = 0); + // DenyAllFilter(const DenyAllFilter &rOther); // Use compiler default + // virtual ~DenyAllFilter(); // Use compiler default + // DenyAllFilter &operator=(const DenyAllFilter &rOther); // Use compiler default + + virtual Decision decide(const LoggingEvent &rEvent) const; + + protected: +#ifndef QT_NO_DEBUG_STREAM + /*! + * Writes all object member variables to the given debug stream \a rDebug + * and returns the stream. + * + * + * %DenyAllFilter(next:QObject(0x0) referencecount:1 ) + * + * \sa QDebug, operator<<(QDebug debug, const LogObject &rLogObject) + */ + virtual QDebug debug(QDebug &rDebug) const; +#endif // QT_NO_DEBUG_STREAM + }; + + + /************************************************************************* + * Operators, Helper + *************************************************************************/ + + + /************************************************************************* + * Inline + *************************************************************************/ + + inline DenyAllFilter::DenyAllFilter(QObject *pParent) : + Filter(pParent) + {} + + inline Filter::Decision DenyAllFilter::decide(const LoggingEvent &rEvent) const + { Q_UNUSED(&rEvent); return Filter::DENY; } + + +} // namespace Log4Qt + + +// Q_DECLARE_TYPEINFO(Log4Qt::DenyAllFilter, Q_MOVABLE_TYPE); // Use default + + +#endif // LOG4QT_DENYALLFILTER_H diff --git a/src/log4qt/src/log4qt/varia/levelmatchfilter.cpp b/src/log4qt/src/log4qt/varia/levelmatchfilter.cpp new file mode 100644 index 0000000..32a3d84 --- /dev/null +++ b/src/log4qt/src/log4qt/varia/levelmatchfilter.cpp @@ -0,0 +1,100 @@ +/****************************************************************************** + * + * package: Log4Qt + * file: levelmatchfilter.cpp + * created: September 2007 + * author: Martin Heinrich + * + * + * Copyright 2007 Martin Heinrich + * + * 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. + * + ******************************************************************************/ + + + +/****************************************************************************** + * Dependencies + ******************************************************************************/ + + +#include "log4qt/varia/levelmatchfilter.h" + +#include +#include "log4qt/loggingevent.h" + + +namespace Log4Qt +{ + + + /************************************************************************** + * Declarations + **************************************************************************/ + + + + /************************************************************************** + * C helper functions + **************************************************************************/ + + + + /************************************************************************** + * Class implementation: Filter + **************************************************************************/ + + + LevelMatchFilter::LevelMatchFilter(QObject *pParent) : + Filter(pParent), + mAcceptOnMatch(true), + mLevelToMatch(Level::NULL_INT) + {} + + + Filter::Decision LevelMatchFilter::decide(const LoggingEvent &rEvent) const + { + if (mLevelToMatch == Level::NULL_INT || + rEvent.level() != mLevelToMatch) + return Filter::NEUTRAL; + + if (mAcceptOnMatch) + return Filter::ACCEPT; + else + return Filter::DENY; + } + + +#ifndef QT_NO_DEBUG_STREAM + QDebug LevelMatchFilter::debug(QDebug &rDebug) const + { + rDebug.nospace() << "LevelMatchFilter(" + << "acceptonmatch:" << mAcceptOnMatch << " " + << "leveltomatch:" << mLevelToMatch.toString() << " " + << "next:" << next() + << "referencecount:" << referenceCount() << " " + << ")"; + return rDebug.space(); + } +#endif // QT_NO_DEBUG_STREAM + + + + /************************************************************************** + * Implementation: Operators, Helper + **************************************************************************/ + + + +} // namespace Log4Qt diff --git a/src/log4qt/src/log4qt/varia/levelmatchfilter.h b/src/log4qt/src/log4qt/varia/levelmatchfilter.h new file mode 100644 index 0000000..b2fb44c --- /dev/null +++ b/src/log4qt/src/log4qt/varia/levelmatchfilter.h @@ -0,0 +1,137 @@ +/****************************************************************************** + * + * package: Log4Qt + * file: levelmatchfilter.h + * created: September 2007 + * author: Martin Heinrich + * + * + * Copyright 2007 Martin Heinrich + * + * 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. + * + ******************************************************************************/ + +#ifndef LOG4QT_LEVELMATCHFILTER_H +#define LOG4QT_LEVELMATCHFILTER_H + + +/****************************************************************************** + * Dependencies + ******************************************************************************/ + +#include "log4qt/spi/filter.h" + +#include "log4qt/level.h" + + +/****************************************************************************** + * Declarations + ******************************************************************************/ + +namespace Log4Qt +{ + + /*! + * \brief The class LevelMatchFilter allows logging events with a specified + * level. + * + * \note The ownership and lifetime of objects of this class are managed. + * See \ref Ownership "Object ownership" for more details. + */ + class LevelMatchFilter : public Filter + { + Q_OBJECT + + /*! + * The property holds if an event is accpeted on a match. + * + * The default is true. + * + * \sa acceptOnMatch(), setAcceptOnMatch() + */ + Q_PROPERTY(bool acceptOnMatch READ acceptOnMatch WRITE setAcceptOnMatch) + + /*! + * The property holds the level to match for this filter. + * + * The default is Level::NULL_INT. + * + * \sa levelToMatch(), setLevelToMatch() + */ + Q_PROPERTY(Level levelToMatch READ levelToMatch WRITE setLevelToMatch) + + public: + LevelMatchFilter(QObject *pParent = 0); + // LevelMatchFilter(const LevelMatchFilter &rOther); // Use compiler default + // virtual ~LevelMatchFilter(); // Use compiler default + // LevelMatchFilter &operator=(const LevelMatchFilter &rOther); // Use compiler default + + bool acceptOnMatch() const; + Level levelToMatch() const; + void setAcceptOnMatch(bool accept); + void setLevelToMatch(Level level); + + virtual Decision decide(const LoggingEvent &rEvent) const; + + protected: +#ifndef QT_NO_DEBUG_STREAM + /*! + * Writes all object member variables to the given debug stream \a rDebug + * and returns the stream. + * + * + * %LevelMatchFilter(acceptonmatch:true leveltomatch:"WARN" + * next:Log4Qt::DenyAllFilter(0x3bce3a8) + * referencecount:1 ) + * + * \sa QDebug, operator<<(QDebug debug, const LogObject &rLogObject) + */ + virtual QDebug debug(QDebug &rDebug) const; +#endif // QT_NO_DEBUG_STREAM + + private: + bool mAcceptOnMatch; + Level mLevelToMatch; + }; + + + /************************************************************************** + * Operators, Helper + **************************************************************************/ + + + /************************************************************************** + * Inline + **************************************************************************/ + + inline bool LevelMatchFilter::acceptOnMatch() const + { return mAcceptOnMatch; } + + inline Level LevelMatchFilter::levelToMatch() const + { return mLevelToMatch; } + + inline void LevelMatchFilter::setAcceptOnMatch(bool accept) + { mAcceptOnMatch = accept; } + + inline void LevelMatchFilter::setLevelToMatch(Level level) + { mLevelToMatch = level; } + + +} // namespace Log4Qt + + +// Q_DECLARE_TYPEINFO(Log4Qt::LevelMatchFilter, Q_MOVABLE_TYPE); // Use default + + +#endif // LOG4QT_LEVELMATCHFILTER_H diff --git a/src/log4qt/src/log4qt/varia/levelrangefilter.cpp b/src/log4qt/src/log4qt/varia/levelrangefilter.cpp new file mode 100644 index 0000000..b219cd9 --- /dev/null +++ b/src/log4qt/src/log4qt/varia/levelrangefilter.cpp @@ -0,0 +1,104 @@ +/****************************************************************************** + * + * package: Log4Qt + * file: levelrangefilter.cpp + * created: September 2007 + * author: Martin Heinrich + * + * + * Copyright 2007 Martin Heinrich + * + * 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. + * + ******************************************************************************/ + + + +/****************************************************************************** + * Dependencies + ******************************************************************************/ + + +#include "log4qt/varia/levelrangefilter.h" + +#include +#include "log4qt/loggingevent.h" + + +namespace Log4Qt +{ + + +/****************************************************************************** + * Declarations + ******************************************************************************/ + + + +/****************************************************************************** + * C helper functions + ******************************************************************************/ + + + +/****************************************************************************** + * Class implementation: Filter + ******************************************************************************/ + + +LevelRangeFilter::LevelRangeFilter(QObject *pParent) : + Filter(pParent), + mAcceptOnMatch(true), + mLevelMin(Level::NULL_INT), + mLevelMax(Level::OFF_INT) +{} + + +Filter::Decision LevelRangeFilter::decide(const LoggingEvent &rEvent) const +{ + if (rEvent.level() < mLevelMin) + return Filter::DENY; + + if (rEvent.level() > mLevelMax) + return Filter::DENY; + + if (mAcceptOnMatch) + return Filter::ACCEPT; + else + return Filter::NEUTRAL; +} + + +#ifndef QT_NO_DEBUG_STREAM +QDebug LevelRangeFilter::debug(QDebug &rDebug) const +{ + rDebug.nospace() << "LevelRangeFilter(" + << "acceptonmatch:" << mAcceptOnMatch << " " + << "levelmin:" << mLevelMin.toString() << " " + << "levelmax:" << mLevelMax.toString() << " " + << "next:" << next() + << "referencecount:" << referenceCount() << " " + << ")"; + return rDebug.space(); +} +#endif // QT_NO_DEBUG_STREAM + + + +/****************************************************************************** + * Implementation: Operators, Helper + ******************************************************************************/ + + + +} // namespace Log4Qt diff --git a/src/log4qt/src/log4qt/varia/levelrangefilter.h b/src/log4qt/src/log4qt/varia/levelrangefilter.h new file mode 100644 index 0000000..013e533 --- /dev/null +++ b/src/log4qt/src/log4qt/varia/levelrangefilter.h @@ -0,0 +1,153 @@ +/****************************************************************************** + * + * package: Log4Qt + * file: levelrangefilter.h + * created: September 2007 + * author: Martin Heinrich + * + * + * Copyright 2007 Martin Heinrich + * + * 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. + * + ******************************************************************************/ + +#ifndef LOG4QT_LEVELRANGEFILTER_H +#define LOG4QT_LEVELRANGEFILTER_H + + +/****************************************************************************** + * Dependencies + ******************************************************************************/ + +#include "log4qt/spi/filter.h" + +#include "log4qt/level.h" + + +/****************************************************************************** + * Declarations + ******************************************************************************/ + +namespace Log4Qt +{ + + /*! + * \brief The class LevelMatchFilter allows logging events with levels in a + * specified range. + * + * \note The ownership and lifetime of objects of this class are managed. + * See \ref Ownership "Object ownership" for more details. + */ + class LevelRangeFilter : public Filter + { + Q_OBJECT + + /*! + * The property holds if an event is accpeted on a match. + * + * The default is true. + * + * \sa acceptOnMatch(), acceptOnMatch() + */ + Q_PROPERTY(bool acceptOnMatch READ acceptOnMatch WRITE setAcceptOnMatch) + + /*! + * The property holds the maximum level of the range for this filter. + * + * The default is Level::OFF_INT. + * + * \sa levelMax(), setLevelMax() + */ + Q_PROPERTY(Level levelMax READ levelMax WRITE setLevelMax) + + /*! + * The property holds the minimum level of the range for this filter. + * + * The default is Level::NULL_INT. + * + * \sa levelMin(), setLevelMin() + */ + Q_PROPERTY(Level levelMin READ levelMin WRITE setLevelMin) + + public: + LevelRangeFilter(QObject *pParent = 0); + // LevelRangeFilter(const LevelRangeFilter &rOther); // Use compiler default + // virtual ~LevelRangeFilter(); // Use compiler default + // LevelRangeFilter &operator=(const LevelRangeFilter &rOther); // Use compiler default + + bool acceptOnMatch() const; + Level levelMax() const; + Level levelMin() const; + void setAcceptOnMatch(bool accept); + void setLevelMax(Level level); + void setLevelMin(Level level); + + virtual Decision decide(const LoggingEvent &rEvent) const; + + protected: + /*! + * Writes all object member variables to the given debug stream \a rDebug + * and returns the stream. + * + * + * %LevelRangeFilter(acceptonmatch:true levelmin:"ERROR" levelmax:"FATAL" + * next:Log4Qt::LevelMatchFilter(0x3bcd960) + * referencecount:1 ) + * + * \sa QDebug, operator<<(QDebug debug, const LogObject &rLogObject) + */ + virtual QDebug debug(QDebug &rDebug) const; + + private: + bool mAcceptOnMatch; + Level mLevelMin; + Level mLevelMax; + }; + + + /************************************************************************** + * Operators, Helper + **************************************************************************/ + + + /************************************************************************** + * Inline + **************************************************************************/ + + inline bool LevelRangeFilter::acceptOnMatch() const + { return mAcceptOnMatch; } + + inline Level LevelRangeFilter::levelMax() const + { return mLevelMax; } + + inline Level LevelRangeFilter::levelMin() const + { return mLevelMin; } + + inline void LevelRangeFilter::setAcceptOnMatch(bool accept) + { mAcceptOnMatch = accept; } + + inline void LevelRangeFilter::setLevelMax(Level level) + { mLevelMax = level; } + + inline void LevelRangeFilter::setLevelMin(Level level) + { mLevelMin = level; } + + +} // namespace Log4Qt + + +// Q_DECLARE_TYPEINFO(Log4Qt::LevelRangeFilter, Q_MOVABLE_TYPE); // Use default + + +#endif // LOG4QT_LEVELRANGEFILTER_H diff --git a/src/log4qt/src/log4qt/varia/listappender.cpp b/src/log4qt/src/log4qt/varia/listappender.cpp new file mode 100644 index 0000000..db20284 --- /dev/null +++ b/src/log4qt/src/log4qt/varia/listappender.cpp @@ -0,0 +1,153 @@ +/****************************************************************************** + * + * package: Log4Qt + * file: listappender.cpp + * created: September 2007 + * author: Martin Heinrich + * + * + * Copyright 2007 Martin Heinrich + * + * 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. + * + ******************************************************************************/ + + + +/****************************************************************************** + * Dependencies + ******************************************************************************/ + + +#include "log4qt/varia/listappender.h" + +#include + + + +namespace Log4Qt +{ + + + /************************************************************************** + * Declarations + **************************************************************************/ + + + + /************************************************************************** + * C helper functions + **************************************************************************/ + + + + /************************************************************************** + * Class implementation: ListAppender + **************************************************************************/ + + + ListAppender::ListAppender(QObject *pParent) : + AppenderSkeleton(pParent), + mConfiguratorList(false), + mList(), + mMaxCount(0) + { + } + + + ListAppender::~ListAppender() + { + } + + + QList ListAppender::list() const + { + QMutexLocker locker(&mObjectGuard); + + return mList; + } + + + void ListAppender::setMaxCount(int n) + { + QMutexLocker locker(&mObjectGuard); + + if (n < 0) + { + logger()->warn("Attempt to set maximum count for appender '%1' to %2. Using zero instead", name(), n); + n = 0; + } + mMaxCount = n; + ensureMaxCount(); + } + + + QList ListAppender::clearList() + { + QMutexLocker locker(&mObjectGuard); + + QList result = mList; + mList.clear(); + return result; + } + + + // bool ListAppender::requiresLayout() const; + + + void ListAppender::append(const LoggingEvent &rEvent) + { + // Q_ASSERT_X(, "ListAppender::append()", "Lock must be held by caller") + + if ((mMaxCount <= 0) || (mList.size() < mMaxCount)) + mList << rEvent; + } + + +#ifndef QT_NO_DEBUG_STREAM + QDebug ListAppender::debug(QDebug &rDebug) const + { + rDebug.nospace() << "ListAppender(" + << "name:" << name() << " " + << "count:" << list().count() << " " + << "filter:" << firstFilter() << " " + << "isactive:" << isActive() << " " + << "isclosed:" << isClosed() << " " + << "maxcount:" << maxCount() << " " + << "referencecount:" << referenceCount() << " " + << "threshold:" << threshold().toString() + << ")"; + return rDebug.space(); + } +#endif // QT_NO_DEBUG_STREAM + + + void ListAppender::ensureMaxCount() + { + // Q_ASSERT_X(, "ListAppender::ensureMaxCount()", "Lock must be held by caller") + + if (mMaxCount <= 0) + return; + + while (mList.size() > mMaxCount) + mList.removeFirst(); + } + + + + /************************************************************************** + * Implementation: Operators, Helper + **************************************************************************/ + + +} // namespace Log4Qt diff --git a/src/log4qt/src/log4qt/varia/listappender.h b/src/log4qt/src/log4qt/varia/listappender.h new file mode 100644 index 0000000..0b35c51 --- /dev/null +++ b/src/log4qt/src/log4qt/varia/listappender.h @@ -0,0 +1,174 @@ +/****************************************************************************** + * + * package: Log4Qt + * file: listappender.h + * created: September 2007 + * author: Martin Heinrich + * + * + * Copyright 2007 Martin Heinrich + * + * 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. + * + ******************************************************************************/ + +#ifndef LOG4QT_LISTAPPENDER_H +#define LOG4QT_LISTAPPENDER_H + + +/****************************************************************************** + * Dependencies + ******************************************************************************/ + +#include "log4qt/appenderskeleton.h" + +#include +#include +#include "log4qt/loggingevent.h" + + +/****************************************************************************** + * Declarations + ******************************************************************************/ + +namespace Log4Qt +{ + + /*! + * \brief The class ListAppender appends logging events to a list for later + * processing. + * + * \note All the functions declared in this class are thread-safe. + * + * \note The ownership and lifetime of objects of this class are managed. + * See \ref Ownership "Object ownership" for more details. + */ + class ListAppender : public AppenderSkeleton + { + Q_OBJECT + + /*! + * The property holds, if the Appender is used by a configurator. + * + * The default value is false for not being a configurator list. + * + * \sa configuratorList(), setConfiguratorList() + */ + Q_PROPERTY(bool configuratorList READ configuratorList WRITE setConfiguratorList) + + /*! + * The property holds the maximum count used by the appender. + * + * The default maximum count is -1 for unlimited. + * + * \sa maxCount(), setMaxCount() + */ + Q_PROPERTY(int maxCount READ maxCount WRITE setMaxCount) + + public: + ListAppender(QObject *pParent = 0); + virtual ~ListAppender(); + private: + ListAppender(const ListAppender &rOther); // Not implemented + ListAppender &operator=(const ListAppender &rOther); // Not implemented + + public: + /*! + * Returns true, if the appender is used by a configurator. Otherweise it returns + * false. + * + * \sa setConfiguratorList() + */ + bool configuratorList() const; + + QList list() const; + int maxCount() const; + + /*! + * Sets that the appender is used by a configurator. If set to true, the appender + * will not be removed from a Logger when Logger::removeAllAppenders()is called. + * This way the appender can collect events raised during the configuration process. + * + * \sa configuratorList(), BasicConfigurator, PropertyConfigurator, + * ConfiguratorHelper::configureError() + */ + void setConfiguratorList(bool isConfiguratorList); + + void setMaxCount(int n); + + QList clearList(); + virtual bool requiresLayout() const; + + protected: + virtual void append(const LoggingEvent &rEvent); + +#ifndef QT_NO_DEBUG_STREAM + /*! + * Writes all object member variables to the given debug stream + * \a rDebug and returns the stream. + * + * + * %ListAppender(name:"LA" count:1 filter:0x41fa488 isactive:true + * isclosed:false maxcount:170 referencecount:1 + * threshold:"TRACE_SET") + * + * \sa QDebug, operator<<(QDebug debug, const LogObject &rLogObject) + */ + virtual QDebug debug(QDebug &rDebug) const; +#endif // QT_NO_DEBUG_STREAM + + /*! + * Ensures that the count of events is less or equal then the maxium + * count. If the list contains too many items, items are deleted from + * the begin of the list. + */ + void ensureMaxCount(); + + private: + volatile bool mConfiguratorList; + QList mList; + volatile int mMaxCount; + }; + + + /************************************************************************** + * Operators, Helper + **************************************************************************/ + + + /************************************************************************** + * Inline + **************************************************************************/ + + inline bool ListAppender::configuratorList() const + { // QMutexLocker locker(&mObjectGuard); // Read/Write of int is safe + return mConfiguratorList; } + + inline int ListAppender::maxCount() const + { return mMaxCount; } + + inline void ListAppender::setConfiguratorList(bool isConfiguratorList) + { // QMutexLocker locker(&mObjectGuard); // Read/Write of int is safe + mConfiguratorList = isConfiguratorList; } + + inline bool ListAppender::requiresLayout() const + { return false; } + + +} // namespace Log4Qt + + +// Q_DECLARE_TYPEINFO(Log4Qt::ListAppender, Q_COMPLEX_TYPE); // Use default + + +#endif // LOG4QT_LISTAPPENDER_H diff --git a/src/log4qt/src/log4qt/varia/nullappender.cpp b/src/log4qt/src/log4qt/varia/nullappender.cpp new file mode 100644 index 0000000..a12ebf2 --- /dev/null +++ b/src/log4qt/src/log4qt/varia/nullappender.cpp @@ -0,0 +1,104 @@ +/****************************************************************************** + * + * package: Log4Qt + * file: nullappender.cpp + * created: September 2007 + * author: Martin Heinrich + * + * + * Copyright 2007 Martin Heinrich + * + * 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. + * + ******************************************************************************/ + + + +/****************************************************************************** + * Dependencies + ******************************************************************************/ + + +#include "log4qt/varia/nullappender.h" + +#include +#include "log4qt/layout.h" +#include "log4qt/loggingevent.h" + + + +namespace Log4Qt +{ + + + /************************************************************************** + * Declarations + **************************************************************************/ + + + + /************************************************************************** + * C helper functions + **************************************************************************/ + + + + /************************************************************************** + * Class implementation: NullAppender + **************************************************************************/ + + + NullAppender::NullAppender(QObject *pParent) : + AppenderSkeleton(false, pParent) + { + } + + + NullAppender::~NullAppender() + { + close(); + } + + + void NullAppender::append(const LoggingEvent &rEvent) + { + Q_UNUSED(rEvent); + } + + +#ifndef QT_NO_DEBUG_STREAM + QDebug NullAppender::debug(QDebug &rDebug) const + { + QString layout_name; + if (layout()) + layout_name = layout()->name(); + + rDebug.nospace() << "NullAppender(" + << "name:" << name() << " " + << "isactive:" << isActive() << " " + << "isclosed:" << isClosed() << " " + << "layout:" << layout_name << " " + << "threshold:" << threshold().toString() << " " + << ")"; + return rDebug.space(); + } +#endif // QT_NO_DEBUG_STREAM + + + + /************************************************************************** + * Implementation: Operators, Helper + **************************************************************************/ + + +} // namespace Log4Qt diff --git a/src/log4qt/src/log4qt/varia/nullappender.h b/src/log4qt/src/log4qt/varia/nullappender.h new file mode 100644 index 0000000..becafb9 --- /dev/null +++ b/src/log4qt/src/log4qt/varia/nullappender.h @@ -0,0 +1,102 @@ +/****************************************************************************** + * + * package: Log4Qt + * file: nullappender.h + * created: September 2007 + * author: Martin Heinrich + * + * + * Copyright 2007 Martin Heinrich + * + * 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. + * + ******************************************************************************/ + +#ifndef LOG4QT_NULLAPPENDER_H +#define LOG4QT_NULLAPPENDER_H + + +/****************************************************************************** + * Dependencies + ******************************************************************************/ + +#include "log4qt/appenderskeleton.h" + + +/****************************************************************************** + * Declarations + ******************************************************************************/ + +namespace Log4Qt +{ + +/*! + * \brief The class NullAppender ignores all requests to append. + * + * \note All the functions declared in this class are thread-safe. + * + * \note The ownership and lifetime of objects of this class are managed. See + * \ref Ownership "Object ownership" for more details. + */ +class NullAppender : public AppenderSkeleton +{ + Q_OBJECT + +public: + NullAppender(QObject *pParent = 0); + virtual ~NullAppender(); +private: + NullAppender(const NullAppender &rOther); // Not implemented + NullAppender &operator=(const NullAppender &rOther); // Not implemented + +public: + virtual bool requiresLayout() const; + +protected: + virtual void append(const LoggingEvent &rEvent); + +#ifndef QT_NO_DEBUG_STREAM + /*! + * Writes all object member variables to the given debug stream \a rDebug and + * returns the stream. + * + * + * %NullAppender() + * + * \sa QDebug, operator<<(QDebug debug, const LogObject &rLogObject) + */ + virtual QDebug debug(QDebug &rDebug) const; +#endif // QT_NO_DEBUG_STREAM +}; + + +/****************************************************************************** + * Operators, Helper + ******************************************************************************/ + + +/****************************************************************************** + * Inline + ******************************************************************************/ + +inline bool NullAppender::requiresLayout() const +{ return false; } + + +} // namespace Log4Qt + + +// Q_DECLARE_TYPEINFO(Log4Qt::NullAppender, Q_COMPLEX_TYPE); // Use default + + +#endif // LOG4QT_NULLAPPENDER_H diff --git a/src/log4qt/src/log4qt/varia/stringmatchfilter.cpp b/src/log4qt/src/log4qt/varia/stringmatchfilter.cpp new file mode 100644 index 0000000..e660b21 --- /dev/null +++ b/src/log4qt/src/log4qt/varia/stringmatchfilter.cpp @@ -0,0 +1,101 @@ +/****************************************************************************** + * + * package: Log4Qt + * file: stringmatchfilter.cpp + * created: September 2007 + * author: Martin Heinrich + * + * + * Copyright 2007 Martin Heinrich + * + * 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. + * + ******************************************************************************/ + + + +/****************************************************************************** + * Dependencies + ******************************************************************************/ + + +#include "log4qt/varia/stringmatchfilter.h" + +#include +#include "log4qt/loggingevent.h" + + +namespace Log4Qt +{ + + + /************************************************************************** + * Declarations + **************************************************************************/ + + + + /************************************************************************** + * C helper functions + **************************************************************************/ + + + + /************************************************************************** + * Class implementation: Filter + **************************************************************************/ + + + StringMatchFilter::StringMatchFilter(QObject *pParent) : + Filter(pParent), + mAcceptOnMatch(true), + mStringToMatch() + {} + + + Filter::Decision StringMatchFilter::decide(const LoggingEvent &rEvent) const + { + if (rEvent.message().isEmpty() || + mStringToMatch.isEmpty() || + rEvent.message().indexOf(mStringToMatch) < 0) + return Filter::NEUTRAL; + + if (mAcceptOnMatch) + return Filter::ACCEPT; + else + return Filter::DENY; + } + + +#ifndef QT_NO_DEBUG_STREAM + QDebug StringMatchFilter::debug(QDebug &rDebug) const + { + rDebug.nospace() << "StringMatchFilter(" + << "acceptonmatch:" << mAcceptOnMatch << " " + << "referencecount:" << referenceCount() << " " + << "stringtomatch:" << mStringToMatch << " " + << "next:" << next() + << ")"; + return rDebug.space(); + } +#endif // QT_NO_DEBUG_STREAM + + + + /************************************************************************** + * Implementation: Operators, Helper + **************************************************************************/ + + + +} // namespace Log4Qt diff --git a/src/log4qt/src/log4qt/varia/stringmatchfilter.h b/src/log4qt/src/log4qt/varia/stringmatchfilter.h new file mode 100644 index 0000000..921460f --- /dev/null +++ b/src/log4qt/src/log4qt/varia/stringmatchfilter.h @@ -0,0 +1,133 @@ +/****************************************************************************** + * + * package: Log4Qt + * file: stringmatchfilter.h + * created: September 2007 + * author: Martin Heinrich + * + * + * Copyright 2007 Martin Heinrich + * + * 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. + * + ******************************************************************************/ + +#ifndef LOG4QT_STRINGMATCHFILTER_H +#define LOG4QT_STRINGMATCHFILTER_H + + +/****************************************************************************** + * Dependencies + ******************************************************************************/ + +#include "log4qt/spi/filter.h" + + +/****************************************************************************** + * Declarations + ******************************************************************************/ + +namespace Log4Qt +{ + + /*! + * \brief The class StringMatchFilter allows logging events with a + * specified level. + * + * \note The ownership and lifetime of objects of this class are managed. + * See \ref Ownership "Object ownership" for more details. + */ + class StringMatchFilter : public Filter + { + Q_OBJECT + + /*! + * The property holds if an event is accpeted on a match. + * + * The default is true. + * + * \sa acceptOnMatch(), acceptOnMatch() + */ + Q_PROPERTY(bool acceptOnMatch READ acceptOnMatch WRITE setAcceptOnMatch) + + /*! + * The property holds the string to match for this filter. + * + * \sa stringToMatch(), setStringToMatch() + */ + Q_PROPERTY(QString stringToMatch READ stringToMatch WRITE setStringToMatch) + + public: + StringMatchFilter(QObject *pParent = 0); + // StringMatchFilter(const StringMatchFilter &rOther); // Use compiler default + // virtual ~StringMatchFilter(); // Use compiler default + // StringMatchFilter &operator=(const StringMatchFilter &rOther); // Use compiler default + + bool acceptOnMatch() const; + QString stringToMatch() const; + void setAcceptOnMatch(bool accept); + void setStringToMatch(const QString &rString); + + virtual Decision decide(const LoggingEvent &rEvent) const; + + protected: +#ifndef QT_NO_DEBUG_STREAM + /*! + * Writes all object member variables to the given debug stream + * \a rDebug and returns the stream. + * + * + * %StringMatchFilter(acceptonmatch:true referencecount:1 + * stringtomatch:"LDAP_STRONG_AUTH_REQUIRED" + * next:Log4Qt::LevelMatchFilter(0x3bdd960) ) + * + * \sa QDebug, operator<<(QDebug debug, const LogObject &rLogObject) + */ + virtual QDebug debug(QDebug &rDebug) const; +#endif // QT_NO_DEBUG_STREAM + + private: + bool mAcceptOnMatch; + QString mStringToMatch; + }; + + + /************************************************************************** + * Operators, Helper + **************************************************************************/ + + + /************************************************************************** + * Inline + **************************************************************************/ + + inline bool StringMatchFilter::acceptOnMatch() const + { return mAcceptOnMatch; } + + inline QString StringMatchFilter::stringToMatch() const + { return mStringToMatch; } + + inline void StringMatchFilter::setAcceptOnMatch(bool accept) + { mAcceptOnMatch = accept; } + + inline void StringMatchFilter::setStringToMatch(const QString &rString) + { mStringToMatch = rString; } + + +} // namespace Log4Qt + + +// Q_DECLARE_TYPEINFO(Log4Qt::StringMatchFilter, Q_MOVABLE_TYPE); // Use default + + +#endif // LOG4QT_STRINGMATCHFILTER_H diff --git a/src/log4qt/src/log4qt/writerappender.cpp b/src/log4qt/src/log4qt/writerappender.cpp new file mode 100644 index 0000000..25a633e --- /dev/null +++ b/src/log4qt/src/log4qt/writerappender.cpp @@ -0,0 +1,288 @@ +/****************************************************************************** + * + * package: Log4Qt + * file: writerappender.cpp + * created: September 2007 + * author: Martin Heinrich + * + * + * Copyright 2007 Martin Heinrich + * + * 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. + * + ******************************************************************************/ + + + +/****************************************************************************** + * Dependencies + ******************************************************************************/ + + +#include "log4qt/writerappender.h" + +#include +#include +#include "log4qt/layout.h" +#include "log4qt/loggingevent.h" + + + +namespace Log4Qt +{ + + + /************************************************************************** + * Declarations + **************************************************************************/ + + + + /************************************************************************** + * C helper functions + **************************************************************************/ + + + + /************************************************************************** + * Class implementation: WriterAppender + **************************************************************************/ + + + WriterAppender::WriterAppender(QObject *pParent) : + AppenderSkeleton(false, pParent), + mpEncoding(0), + mpWriter(0), + mImmediateFlush(true) + { + } + + + WriterAppender::WriterAppender(Layout *pLayout, + QObject *pParent) : + AppenderSkeleton(false, pParent), + mpEncoding(0), + mpWriter(0), + mImmediateFlush(true) + { + setLayout(pLayout); + } + + + WriterAppender::WriterAppender(Layout *pLayout, + QTextStream *pTextStream, + QObject *pParent) : + AppenderSkeleton(false, pParent), + mpEncoding(0), + mpWriter(pTextStream), + mImmediateFlush(true) + { + setLayout(pLayout); + } + + + WriterAppender::~WriterAppender() + { + close(); + } + + + void WriterAppender::setEncoding(QTextCodec *pEncoding) + { + QMutexLocker locker(&mObjectGuard); + + if (mpEncoding == pEncoding) + return; + + mpEncoding = pEncoding; + if (mpWriter) + { + if (mpEncoding) + mpWriter->setCodec(mpEncoding); + else + mpWriter->setCodec(QTextCodec::codecForLocale()); + } + } + + + void WriterAppender::setWriter(QTextStream *pTextStream) + { + QMutexLocker locker(&mObjectGuard); + + closeWriter(); + + mpWriter = pTextStream; + if (mpEncoding && mpWriter) + mpWriter->setCodec(mpEncoding); + writeHeader(); + } + + + void WriterAppender::activateOptions() + { + QMutexLocker locker(&mObjectGuard); + + if (!writer()) + { + LogError e = LOG4QT_QCLASS_ERROR(QT_TR_NOOP("Activation of Appender '%1' that requires writer and has no writer set"), + APPENDER_ACTIVATE_MISSING_WRITER_ERROR); + e << name(); + logger()->error(e); + return; + } + + AppenderSkeleton::activateOptions(); + } + + + void WriterAppender::close() + { + QMutexLocker locker(&mObjectGuard); + + if (isClosed()) + return; + + AppenderSkeleton::close(); + closeWriter(); + } + + + bool WriterAppender::requiresLayout() const + { + return true; + } + + + void WriterAppender::append(const LoggingEvent &rEvent) + { + // Q_ASSERT_X(, "WriterAppender::append()", "Lock must be held by caller"); + Q_ASSERT_X(layout(), "WriterAppender::append()", "Layout must not be null"); + + QString message(layout()->format(rEvent)); + + *mpWriter << message; + if (handleIoErrors()) + return; + + if (immediateFlush()) + { + mpWriter->flush(); + if (handleIoErrors()) + return; + } + } + + + bool WriterAppender::checkEntryConditions() const + { + // Q_ASSERT_X(, "WriterAppender::checkEntryConditions()", "Lock must be held by caller") + + if (!writer()) + { + LogError e = LOG4QT_QCLASS_ERROR(QT_TR_NOOP("Use of appender '%1' without a writer set"), + APPENDER_USE_MISSING_WRITER_ERROR); + e << name(); + logger()->error(e); + return false; + } + + return AppenderSkeleton::checkEntryConditions(); + } + + + void WriterAppender::closeWriter() + { + // Q_ASSERT_X(, "WriterAppender::closeWriter()", "Lock must be held by caller") + + if (!mpWriter) + return; + + writeFooter(); + mpWriter = 0; + } + + +#ifndef QT_NO_DEBUG_STREAM + QDebug WriterAppender::debug(QDebug &rDebug) const + { + QString layout_name; + if (layout()) + layout_name = layout()->name(); + QString codec_name; + if (encoding()) + codec_name = QLatin1String(encoding()->name()); + + rDebug.nospace() << "WriterAppender(" + << "name:" << name() << " " + << "encoding:" << codec_name << " " + << "filter:" << firstFilter() + << "immediateFlush:" << immediateFlush() + << "isactive:" << isActive() + << "isclosed:" << isClosed() + << "layout:" << layout_name + << "referencecount:" << referenceCount() << " " + << "threshold:" << threshold().toString() + << "writer:" << writer() + << ")"; + return rDebug.space(); + } +#endif // QT_NO_DEBUG_STREAM + + + bool WriterAppender::handleIoErrors() const + { + return false; + } + + + void WriterAppender::writeFooter() const + { + // Q_ASSERT_X(, "WriterAppender::writeFooter()", "Lock must be held by caller") + + if (!layout() || !mpWriter) + return; + + QString footer = layout()->footer(); + if (footer.isEmpty()) + return; + + *mpWriter << footer << Layout::endOfLine(); + if (handleIoErrors()) + return; + } + + + void WriterAppender::writeHeader() const + { + // Q_ASSERT_X(, "WriterAppender::writeHeader()", "Lock must be held by caller") + + if (!layout() || !mpWriter) + return; + + QString header = layout()->header(); + if (header.isEmpty()) + return; + + *mpWriter << header << Layout::endOfLine(); + if (handleIoErrors()) + return; + } + + + + /****************************************************************************** + * Implementation: Operators, Helper + ******************************************************************************/ + + +} // namespace Log4Qt diff --git a/src/log4qt/src/log4qt/writerappender.h b/src/log4qt/src/log4qt/writerappender.h new file mode 100644 index 0000000..5c8da09 --- /dev/null +++ b/src/log4qt/src/log4qt/writerappender.h @@ -0,0 +1,200 @@ +/****************************************************************************** + * + * package: Log4Qt + * file: writerappender.h + * created: September 2007 + * author: Martin Heinrich + * + * + * Copyright 2007 Martin Heinrich + * + * 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. + * + ******************************************************************************/ + +#ifndef LOG4QT_WRITERAPPENDER_H +#define LOG4QT_WRITERAPPENDER_H + + +/****************************************************************************** + * Dependencies + ******************************************************************************/ + +#include "log4qt/appenderskeleton.h" + + +/****************************************************************************** + * Declarations + ******************************************************************************/ + +class QTextCodec; +class QTextStream; + +namespace Log4Qt +{ + + /*! + * \brief The class WriterAppender appends log events to a QTextStream. + * + * \note All the functions declared in this class are thread-safe. + *   + * \note The ownership and lifetime of objects of this class are managed. + * See \ref Ownership "Object ownership" for more details. + */ + class WriterAppender : public AppenderSkeleton + { + Q_OBJECT + + /*! + * The property holds the codec the appender uses. + * + * The default is null to use the codec the writer has set. + * + * \sa encoding(), setEncoding() + */ + Q_PROPERTY(QTextCodec* encoding READ encoding WRITE setEncoding) + + /*! + * The property holds the writer the appender uses. + * + * \sa writer(), setWriter() + */ + Q_PROPERTY(QTextStream* writer READ writer WRITE setWriter) + + /*! + * The property holds, if the writer flushes after all write operations. + * + * The default is true for flushing. + * + * \sa immediateFlush(), setImmediateFlush() + */ + Q_PROPERTY(bool immediateFlush READ immediateFlush WRITE setImmediateFlush) + + public: + WriterAppender(QObject *pParent = 0); + WriterAppender(Layout *pLayout, + QObject *pParent = 0); + WriterAppender(Layout *pLayout, + QTextStream *pTextStream, + QObject *pParent = 0); + virtual ~WriterAppender(); + private: + WriterAppender(const WriterAppender &rOther); // Not implemented + WriterAppender &operator=(const WriterAppender &rOther); // Not implemented + + public: + virtual bool requiresLayout() const; + QTextCodec *encoding() const; + bool immediateFlush() const; + QTextStream *writer() const; + + /*! + * Sets the codec used by the writer to \a pTextCoded. + * + * If a codec is set with setEncoding, it will overwrite the codec set + * in the text stream. A subsequent call with \a pTextCoded equals null + * will resets the codec to the default QTextCodec::codecForLocale(). + * + * \sa encoding(), QTextSream::setCodec(), QTextCodec::codecForLocale() + */ + void setEncoding(QTextCodec *pTextCodec); + void setImmediateFlush(bool immediateFlush); + void setWriter(QTextStream *pTextStream); + + virtual void activateOptions(); + virtual void close(); + + protected: + virtual void append(const LoggingEvent &rEvent); + + /*! + * Tests if all entry conditions for using append() in this class are + * met. + * + * If a conditions is not met, an error is logged and the function + * returns false. Otherwise the result of + * AppenderSkeleton::checkEntryConditions() is returned. + * + * The checked conditions are: + * - A writer has been set (APPENDER_USE_MISSING_WRITER_ERROR) + * + * The function is called as part of the checkEntryConditions() chain + * started by AppenderSkeleton::doAppend(). + * + * \sa AppenderSkeleton::doAppend(), + * AppenderSkeleton::checkEntryConditions() + */ + virtual bool checkEntryConditions() const; + + void closeWriter(); + +#ifndef QT_NO_DEBUG_STREAM + /*! + * Writes all object member variables to the given debug stream + * \a rDebug and returns the stream. + * + * + * %WriterAppender(name:"WA" encoding:"" immediateFlush:true + * isactive:false isclosed:false layout:"TTCC" + * referencecount:1 threshold:"NULL" + * writer:0x0) + * + * \sa QDebug, operator<<(QDebug debug, const LogObject &rLogObject ) + */ + virtual QDebug debug(QDebug &rDebug) const; +#endif // QT_NO_DEBUG_STREAM + + virtual bool handleIoErrors() const; + void writeFooter() const; + void writeHeader() const; + + private: + QTextCodec *mpEncoding; + QTextStream *mpWriter; + volatile bool mImmediateFlush; + }; + + + /************************************************************************** + * Operators, Helper + **************************************************************************/ + + + /************************************************************************** + * Inline + **************************************************************************/ + + inline QTextCodec *WriterAppender::encoding() const + { QMutexLocker locker(&mObjectGuard); + return mpEncoding; } + + inline bool WriterAppender::immediateFlush() const + { // QMutexLocker locker(&mObjectGuard); // Read/Write of int is safe + return mImmediateFlush; } + + inline QTextStream *WriterAppender::writer() const + { // QMutexLocker locker(&mObjectGuard); // Read/Write of int is safe + return mpWriter; } + + inline void WriterAppender::setImmediateFlush(bool immediateFlush) + { // QMutexLocker locker(&mObjectGuard); // Read/Write of int is safe + mImmediateFlush = immediateFlush; } + + +} // namespace Log4Qt + + +// Q_DECLARE_TYPEINFO(Log4Qt::WriterAppender, Q_COMPLEX_TYPE); // Use default + + +#endif // LOG4QT_WRITERAPPENDER_H diff --git a/src/log4qt/tests/log4qttest.cpp b/src/log4qt/tests/log4qttest.cpp new file mode 100644 index 0000000..ce47234 --- /dev/null +++ b/src/log4qt/tests/log4qttest.cpp @@ -0,0 +1,2082 @@ +/****************************************************************************** + * + * package: Log4Qt + * file: log4qttest.cpp + * created: September 2007 + * author: Martin Heinrich + * + * + * Copyright 2007 Martin Heinrich + * + * 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. + * + ******************************************************************************/ + +/****************************************************************************** + * Dependencies + ******************************************************************************/ + +#include "log4qttest.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "log4qt/basicconfigurator.h" +#include "log4qt/consoleappender.h" +#include "log4qt/dailyrollingfileappender.h" +#include "log4qt/fileappender.h" +#include "log4qt/helpers/configuratorhelper.h" +#include "log4qt/helpers/datetime.h" +#include "log4qt/helpers/factory.h" +#include "log4qt/helpers/initialisationhelper.h" +#include "log4qt/helpers/optionconverter.h" +#include "log4qt/helpers/patternformatter.h" +#include "log4qt/helpers/properties.h" +#include "log4qt/logmanager.h" +#include "log4qt/loggerrepository.h" +#include "log4qt/patternlayout.h" +#include "log4qt/propertyconfigurator.h" +#include "log4qt/rollingfileappender.h" +#include "log4qt/simplelayout.h" +#include "log4qt/ttcclayout.h" +#include "log4qt/varia/denyallfilter.h" +#include "log4qt/varia/levelmatchfilter.h" +#include "log4qt/varia/levelrangefilter.h" +#include "log4qt/varia/stringmatchfilter.h" + + + +using namespace Log4Qt; + + +/****************************************************************************** + *Declarations + ******************************************************************************/ + + + +/****************************************************************************** + * C helper functions + ******************************************************************************/ + + +QTEST_MAIN(Log4QtTest) +LOG4QT_DECLARE_STATIC_LOGGER(test_logger, Test::TestLog4Qt) + + + +/****************************************************************************** + * Class implementation: Log4QtTest + ******************************************************************************/ + + + +Log4QtTest::Log4QtTest() : +QObject(), +mSkipLongTests(false), +mTemporaryDirectory(), +mpLoggingEvents(0), +mDefaultProperties(), +mProperties(&mDefaultProperties) +{ + // mSkipLongTests = true; +} + + +Log4QtTest::~Log4QtTest() +{ +} + + + +/****************************************************************************** + * log4qt/helpers */ + +void Log4QtTest::initTestCase() +{ + // Logging + LogManager::resetConfiguration(); + + // File system + QString name = QDir::tempPath() + "/Log4QtTest_" + + QDateTime::currentDateTime().toString("yyyyMMdd_hhmmss"); + if (!mTemporaryDirectory.mkdir(name)) + QFAIL("Creation of temporary directory failed"); + mTemporaryDirectory.setPath(name); + qDebug() << "Using temporaray directory: " << mTemporaryDirectory.path(); + + // Appender to track events generated by Log4Qt + mpLoggingEvents = new Log4Qt::ListAppender(this); + mpLoggingEvents->retain(); + mpLoggingEvents->setName("Log4QtTest"); + mpLoggingEvents->setConfiguratorList(true); + resetLogging(); +} + + +void Log4QtTest::cleanupTestCase() +{ + LogManager::resetConfiguration(); + + if (!deleteDirectoryTree(mTemporaryDirectory.path())) + QFAIL("Cleanup of temporary directory failed"); + mpLoggingEvents->release(); +} + + +void Log4QtTest::DateTime_compability_data() +{ + QTest::addColumn("pattern"); + + QTest::newRow("date d") << "d"; + QTest::newRow("date dd") << "dd"; + QTest::newRow("date ddd") << "ddd"; + QTest::newRow("date dddd") << "dddd"; + QTest::newRow("date M") << "M"; + QTest::newRow("date MM") << "MM"; + QTest::newRow("date MMM") << "MMM"; + QTest::newRow("date MMMM") << "MMMM"; + QTest::newRow("date YY") << "YY"; + QTest::newRow("date YYYY") << "YYYY"; + QTest::newRow("time h") << "h"; + QTest::newRow("time hh") << "hh"; + QTest::newRow("time H") << "H"; + QTest::newRow("time HH") << "HH"; + QTest::newRow("time m") << "m"; + QTest::newRow("time mm") << "mm"; + QTest::newRow("time s") << "s"; + QTest::newRow("time ss") << "ss"; + QTest::newRow("time z") << "z"; + QTest::newRow("time zz") << "zz"; + QTest::newRow("time a") << "a"; + QTest::newRow("time ap") << "ap"; + QTest::newRow("time A") << "A"; + QTest::newRow("time AP") << "AP"; + QTest::newRow("datetime") << ""; + QTest::newRow("datetime HHh") << "HHh"; + QTest::newRow("datetime 'M'M'd'd'y'yyhh:mm:ss") << "'M'M'd'd'y'yyhh:mm:ss"; + QTest::newRow("datetime M.d.s") << "M.d.s"; + QTest::newRow("datetime YYYY-MM-ddTHH:mm:ss") << "YYYY-MM-ddTHH:mm:ss"; + QTest::newRow("datetime YYYY-MM-ddTHH:mm:ss.zzz") << "YYYY-MM-ddTHH:mm:ss.zzz"; + QTest::newRow("datetime yyyy-MM-dd HH:mm:ss,zzz") << "yyyy-MM-dd HH:mm:ss,zzz"; + QTest::newRow("datetime dd MMM yyyy HH:mm:ss.zzz") << "dd MMM yyyy HH:mm:ss.zzz"; + QTest::newRow("datetime HH:mm:ss.zzz") << "HH:mm:ss.zzz"; + // Quotes are not handled like in JAVA. 'x''x' -> xx not x'x + QTest::newRow("datetime 'This is a'''' test'") << "'This is a'''' test'"; + // Qt does not ignore literals outside of quotes x'x' -> xx not x + QTest::newRow("datetime This 'is a'''' test'") << "This 'is a'''' test'"; + // HH is handled by toString even if not documented + QTest::newRow("datetime HH:mm AP") << "HH:mm AP"; +} + + +void Log4QtTest::DateTime_compability() +{ + QDateTime reference = QDateTime(QDate(2001, 9, 7), QTime(15, 7, 5, 9)); + QDateTime q_date_time(reference); + DateTime date_time(reference); + + QFETCH(QString, pattern); + QCOMPARE(date_time.toString(pattern), q_date_time.toString(pattern)); +} + + +void Log4QtTest::DateTime_week_data() +{ + QTest::addColumn("datetime"); + QTest::addColumn("pattern"); + QTest::addColumn("result"); + + QTest::newRow("week 6") << QDateTime(QDate(2001,2,9), QTime(15,7,5,9)) << "w" << "6"; + QTest::newRow("week 06") << QDateTime(QDate(2001,2,9), QTime(15,7,5,9)) << "ww" << "06"; + QTest::newRow("week 36") << QDateTime(QDate(2001,9,7), QTime(15,7,5,9)) << "w" << "36"; +} + + +void Log4QtTest::DateTime_week() +{ + QFETCH(QDateTime, datetime); + QFETCH(QString, pattern); + QFETCH(QString, result); + + QCOMPARE(static_cast(datetime).toString(pattern), result); +} + + +void Log4QtTest::DateTime_milliseconds_data() +{ + QTest::addColumn("datetime"); + QTest::addColumn("milliseconds"); + + QTest::newRow("2001-09-07 15:07:05.009") << QDateTime(QDate(2001,9,7), QTime(15,7,5,9), Qt::UTC) << Q_INT64_C(999875225009); +} + + +void Log4QtTest::DateTime_milliseconds() +{ + QFETCH(QDateTime, datetime); + QFETCH(qint64, milliseconds); + + QCOMPARE(DateTime(datetime).toMilliSeconds(), milliseconds); + QCOMPARE(DateTime::fromMilliSeconds(milliseconds).toUTC(), datetime); +} + + +void Log4QtTest::PatternFormatter_data() +{ + QTest::addColumn("event"); + QTest::addColumn("pattern"); + QTest::addColumn("result"); + QTest::addColumn("event_count"); + + // Create end of line + QString eol; +#ifdef Q_OS_WIN32 + eol = QLatin1String("\r\n"); +#else + eol = QLatin1String("\n"); +#endif // Q_OS_WIN32 + // Prepare event data + int relative_offset = 17865; + qint64 relative_timestamp = InitialisationHelper::startTime() + relative_offset; + QString relative_string = QString::number(relative_offset); + qint64 absolute_timestamp = + DateTime(QDateTime(QDate(2001,9,7), QTime(15,7,5,9))).toMilliSeconds(); + QHash properties; + properties.insert("A", "a"); + properties.insert("B", "b"); + properties.insert("C", "c"); + + QTest::newRow("Default conversion") + << LoggingEvent(test_logger(), + Level(Level::DEBUG_INT), + "This is the message") + << "%m%n" + << "This is the message" + eol + << 0; + QTest::newRow("TTCC conversion") + << LoggingEvent(test_logger(), + Level(Level::DEBUG_INT), + "This is the message", + "NDC", + properties, + "main", + relative_timestamp) + << "%r [%t] %p %c %x - %m%n" + << relative_string + " [main] DEBUG Test::TestLog4Qt NDC - This is the message" + eol + << 0; + QTest::newRow("Java class documentation example 1") + << LoggingEvent(test_logger(), + Level(Level::WARN_INT), + "This is the message", + "NDC", + properties, + "main", + relative_timestamp) + << "%-5p [%t]: %m%n" + << "WARN [main]: This is the message" + eol + << 0; + QTest::newRow("Java class documentation example 2") + << LoggingEvent(test_logger(), + Level(Level::INFO_INT), + "This is the message", + "NDC", + properties, + "main", + relative_timestamp) + << "%r [%t] %-5p %c %x - %m%n" + << relative_string + " [main] INFO Test::TestLog4Qt NDC - This is the message" + eol + << 0; + QTest::newRow("Java class documentation example 2") + << LoggingEvent(test_logger(), + Level(Level::INFO_INT), + "This is the message", + "NDC", + properties, + "main", + relative_timestamp) + << "%-6r [%15.15t] %-5p %30.30c %x - %m%n" + << relative_string + " [ main] INFO Test::TestLog4Qt NDC - This is the message" + eol + << 0; + QTest::newRow("Java class documentation example 2, truncating") + << LoggingEvent(test_logger(), + Level(Level::INFO_INT), + "This is the message", + "NDC", + properties, + "threadwithextralongname", + relative_timestamp) + << "%-6r [%15.15t] %-5p %30.30c %x - %m%n" + << relative_string + " [threadwithextra] INFO Test::TestLog4Qt NDC - This is the message" + eol + << 0; + QTest::newRow("TTCC with ISO date") + << LoggingEvent(test_logger(), + Level(Level::DEBUG_INT), + "This is the message", + "NDC", + properties, + "main", + absolute_timestamp) + << "%d{ISO8601} [%t] %p %c %x - %m%n" + << "2001-09-07 15:07:05.009 [main] DEBUG Test::TestLog4Qt NDC - This is the message" + eol + << 0; + + resetLogging(); +} + + +void Log4QtTest::PatternFormatter() +{ + QFETCH(LoggingEvent, event); + QFETCH(QString, pattern); + QFETCH(QString, result); + QFETCH(int, event_count); + + Log4Qt::PatternFormatter pattern_formatter(pattern); + QCOMPARE(pattern_formatter.format(event), result); + + QCOMPARE(mpLoggingEvents->list().count(), event_count); +} + + +void Log4QtTest::Properties_default_data() +{ + mDefaultProperties.clear(); + mDefaultProperties.setProperty("X", "x"); + + mProperties.clear(); + mProperties.setProperty("A", "a"); + mProperties.setProperty("B", ""); + mProperties.setProperty("C", QString()); + + QTest::addColumn("key"); + QTest::addColumn("value"); + + QTest::newRow("Existing value") << "A" << "a"; + QTest::newRow("Empty value") << "B" << ""; + QTest::newRow("Null value") << "C" << ""; + QTest::newRow("Default value") << "X" << "x"; + QTest::newRow("Non existing value") << "D" << QString(); +} + + +void Log4QtTest::Properties_default() +{ + QFETCH(QString, key); + QFETCH(QString, value); + + QCOMPARE(mProperties.property(key), value); +} + + +void Log4QtTest::Properties_names() +{ + mDefaultProperties.clear(); + mDefaultProperties.setProperty("X", "x"); + + mProperties.clear(); + mProperties.setProperty("A", "a"); + mProperties.setProperty("B", ""); + + QStringList property_names = mProperties.propertyNames(); + QCOMPARE(property_names.count(), 3); + QVERIFY(property_names.contains("A")); + QVERIFY(property_names.count("B")); + QVERIFY(property_names.count("X")); +} + + +void Log4QtTest::Properties_load_device_data() +{ + QTest::addColumn("buffer"); + QTest::addColumn("property_count"); + QTest::addColumn("key"); + QTest::addColumn("value"); + QTest::addColumn("event_count"); + + QByteArray buffer; + QBuffer device(&buffer); + QTextStream stream(&device); + + buffer.clear(); + device.open(QIODevice::WriteOnly); + stream << "Truth = Beauty" << endl; + device.close(); + QTest::newRow("Java class documentation example 1a") + << buffer << 1 << "Truth" << "Beauty" << 0; + + buffer.clear(); + device.open(QIODevice::WriteOnly); + stream << " Truth:Beauty" << endl; + device.close(); + QTest::newRow("Java class documentation example 1b") + << buffer << 1 << "Truth" << "Beauty" << 0; + + buffer.clear(); + device.open(QIODevice::WriteOnly); + stream << "Truth :Beauty" << endl; + device.close(); + QTest::newRow("Java class documentation example 1c") + << buffer << 1 << "Truth" << "Beauty" << 0; + + buffer.clear(); + device.open(QIODevice::WriteOnly); + stream << "fruits apple, banana, pear, \\" << endl; + stream << " cantaloupe, watermelon, \\" << endl; + stream << " kiwi, mango" << endl; + device.close(); + QTest::newRow("Java class documentation example 2") + << buffer << 1 << "fruits" + << "apple, banana, pear, cantaloupe, watermelon, kiwi, mango" << 0; + + buffer.clear(); + device.open(QIODevice::WriteOnly); + stream << "cheese" << endl; + device.close(); + QTest::newRow("Java class documentation example 3") + << buffer << 1 << "cheese" << "" << 0; + + buffer.clear(); + device.open(QIODevice::WriteOnly); + stream << "K\\ e\\=\\:y Value" << endl; + device.close(); + QTest::newRow("Key escape sequences") + << buffer << 1 << "K e=:y" << "Value" << 0; + + buffer.clear(); + device.open(QIODevice::WriteOnly); + stream << "Key V\\t\\n\\ra\\\\l\\\"u\\\'e" << endl; + device.close(); + QTest::newRow("Value escape sequences") + << buffer << 1 << "Key" << "V\t\n\ra\\l\"u\'e" << 0; + + buffer.clear(); + device.open(QIODevice::WriteOnly); + stream << "Key\\t Value\\j" << endl; + device.close(); + QTest::newRow("Invalid escape sequences") + << buffer << 1 << "Keyt" << "Valuej" << 2; + + buffer.clear(); + device.open(QIODevice::WriteOnly); + stream << "Key Valu\\u006fe" << endl; + device.close(); + QTest::newRow("Unicode escape sequence") + << buffer << 1 << "Key" << "Valuoe" << 0; + + buffer.clear(); + device.open(QIODevice::WriteOnly); + stream << "Key Value\\u6f" << endl; + device.close(); + QTest::newRow("Unicode escape sequence at the end") + << buffer << 1 << "Key" << "Valueo" << 0; + + buffer.clear(); + device.open(QIODevice::WriteOnly); + stream << ": Value" << endl; + device.close(); + QTest::newRow("Empty key") + << buffer << 1 << "" << "Value" << 1; + + resetLogging(); +} + + +void Log4QtTest::Properties_load_device() +{ + QFETCH(QByteArray, buffer); + QFETCH(int, property_count); + QFETCH(QString, key); + QFETCH(QString, value); + QFETCH(int, event_count); + + mpLoggingEvents->clearList(); + + QBuffer device(&buffer); + QTextStream stream(&device); + device.open(QIODevice::ReadOnly); + + Properties properties; + properties.load(&device); + + QCOMPARE(properties.count(), property_count); + QVERIFY(properties.contains(key)); + QCOMPARE(properties.value(key), value); + QCOMPARE(mpLoggingEvents->list().count(), event_count); +} + + +void Log4QtTest::Properties_load_settings() +{ + QSettings settings(mTemporaryDirectory.path() + + "/PropetiesLoadSettings.ini", QSettings::IniFormat); + QBitArray bit_array(5, true); + + settings.setValue("A", "a"); + settings.setValue("Group/B", "b"); + settings.setValue("Group/C", true); + settings.setValue("Group/D", bit_array); + settings.setValue("Group/Subgroup/E", "e"); + + settings.beginGroup("Group"); + Properties properties; + properties.load(settings); + + QCOMPARE(properties.count(), 3); + QVERIFY(properties.contains("B")); + QCOMPARE(properties.value("B"), QString("b")); + QVERIFY(properties.contains("C")); + QCOMPARE(properties.value("C"), QString("true")); + QVERIFY(properties.contains("D")); + QCOMPARE(properties.value("D"), QString()); +} + + + +/****************************************************************************** + * OptionConverter requires Properties */ + + +void Log4QtTest::OptionConverter_boolean_data() +{ + QTest::addColumn("value"); + QTest::addColumn("default_value"); + QTest::addColumn("result"); + QTest::addColumn("event_count"); + + QTest::newRow("true") << "true" << false << true << 0; + QTest::newRow("enabled") << "enabled" << false << true << 0; + QTest::newRow("1") << "1" << false << true << 0; + QTest::newRow("false") << "false" << true << false << 0; + QTest::newRow("disabled") << "disabled" << true << false << 0; + QTest::newRow("0") << "0" << true << false << 0; + QTest::newRow("Case") << "tRuE" << false << true << 0; + QTest::newRow("Trim") << " true " << false << true << 0; + QTest::newRow("No Boolean") << "NoBool" << false << false << 1; + + resetLogging(); +} + + +void Log4QtTest::OptionConverter_boolean() +{ + QFETCH(QString, value); + QFETCH(bool, default_value); + QFETCH(bool, result); + QFETCH(int, event_count); + + mpLoggingEvents->clearList(); + QCOMPARE(OptionConverter::toBoolean(value, default_value), result); + QCOMPARE(mpLoggingEvents->list().count(), event_count); +} + + +void Log4QtTest::OptionConverter_filesize_data() +{ + QTest::addColumn("value"); + QTest::addColumn("result_ok"); + QTest::addColumn("result"); + QTest::addColumn("event_count"); + + QTest::newRow("Int") + << "135" << true << Q_INT64_C(135) << 0; + QTest::newRow("Trim") + << " 135 " << true << Q_INT64_C(135) << 0; + QTest::newRow("KB") + << "2KB" << true << Q_INT64_C(2048) << 0; + QTest::newRow("KB case") + << "2kb" << true << Q_INT64_C(2048) << 0; + QTest::newRow("KB trim") + << " 2KB " << true << Q_INT64_C(2048) << 0; + QTest::newRow("MB") + << "100MB" << true << Q_INT64_C(104857600) << 0; + QTest::newRow("GB") + << "2GB" << true << Q_INT64_C(2147483648) << 0; + QTest::newRow("Invalid negative") + << "-1" << false << Q_INT64_C(0) << 1; + QTest::newRow("Invalid character") + << "x" << false << Q_INT64_C(0) << 1; + QTest::newRow("Invalid character with unit") + << "xkb" << false << Q_INT64_C(0) << 1; + QTest::newRow("Invalid additional text") + << "2KBx" << false << Q_INT64_C(0) << 1; + + resetLogging(); +} + + +void Log4QtTest::OptionConverter_filesize() +{ + QFETCH(QString, value); + QFETCH(bool, result_ok); + QFETCH(qint64, result); + QFETCH(int, event_count); + + mpLoggingEvents->clearList(); + bool ok; + QCOMPARE(OptionConverter::toFileSize(value, &ok), result); + QCOMPARE(ok, result_ok); + QCOMPARE(mpLoggingEvents->list().count(), event_count); +} + + +void Log4QtTest::OptionConverter_int_data() +{ + QTest::addColumn("value"); + QTest::addColumn("result_ok"); + QTest::addColumn("result"); + QTest::addColumn("event_count"); + + QTest::newRow("Positive") << "12" << true << 12 << 0; + QTest::newRow("Negative") << "-1" << true << -1 << 0; + QTest::newRow("Trim") << " 12 " << true << 12 << 0; + QTest::newRow("No integer") << "12x" << false << 0 << 1; + + resetLogging(); +} + + +void Log4QtTest::OptionConverter_int() +{ + QFETCH(QString, value); + QFETCH(bool, result_ok); + QFETCH(int, result); + QFETCH(int, event_count); + + mpLoggingEvents->clearList(); + bool ok; + QCOMPARE(OptionConverter::toInt(value, &ok), result); + QCOMPARE(ok, result_ok); + QCOMPARE(mpLoggingEvents->list().count(), event_count); +} + + +void Log4QtTest::OptionConverter_level_data() +{ + QTest::addColumn("value"); + QTest::addColumn("default_value"); + QTest::addColumn("result"); + QTest::addColumn("event_count"); + + QTest::newRow("Case") + << "WaRn" + << Log4Qt::Level(Log4Qt::Level::ERROR_INT) + << Log4Qt::Level(Log4Qt::Level::WARN_INT) + << 0; + QTest::newRow("Trim") + << " warn " + << Log4Qt::Level(Log4Qt::Level::ERROR_INT) + << Log4Qt::Level(Log4Qt::Level::WARN_INT) + << 0; + QTest::newRow("Default") + << "NoLevel" + << Log4Qt::Level(Log4Qt::Level::ERROR_INT) + << Log4Qt::Level(Log4Qt::Level::ERROR_INT) + << 2; // One from Level + one from OptionConverter + + resetLogging(); +} + + +void Log4QtTest::OptionConverter_level() +{ + QFETCH(QString, value); + QFETCH(Log4Qt::Level, default_value); + QFETCH(Log4Qt::Level, result); + QFETCH(int, event_count); + + mpLoggingEvents->clearList(); + QCOMPARE(OptionConverter::toLevel(value, default_value), result); + QCOMPARE(mpLoggingEvents->list().count(), event_count); +} + + +void Log4QtTest::OptionConverter_substitution_data() +{ + mDefaultProperties.clear(); + mProperties.clear(); + + QTest::addColumn("key"); + QTest::addColumn("value"); + QTest::addColumn("result"); + QTest::addColumn("event_count"); + + QTest::newRow("Existing value") + << "A" << "a" << "a" << 0; + QTest::newRow("Existing value") + << "B" << "b" << "b" << 0; + QTest::newRow("Empty value") + << "C" << "" << "" << 0; + QTest::newRow("Null value") + << "D" << QString() << "" << 0; + QTest::newRow("Substitution") + << "S1" << "begin${A}end" << "beginaend" << 0; + QTest::newRow("Substitution with two values") + << "S2" << "begin${A}end${B}" << "beginaendb" << 0; + QTest::newRow("Substitution recursive") + << "S3" << "${S1}" << "beginaend" << 0; + QTest::newRow("Substitution missing bracket") + << "S4" << "begin${end" << "begin" << 1; + QTest::newRow("Substitution spare brackets") + << "S5" << "begin}${A}}end" << "begin}a}end" << 0; +} + + +void Log4QtTest::OptionConverter_substitution() +{ + QFETCH(QString, key); + QFETCH(QString, value); + QFETCH(QString, result); + QFETCH(int, event_count); + + mpLoggingEvents->clearList(); + mProperties.setProperty(key, value); + QCOMPARE(OptionConverter::findAndSubst(mProperties, key), result); + QCOMPARE(mpLoggingEvents->list().count(), event_count); +} + + +void Log4QtTest::OptionConverter_target_data() +{ + QTest::addColumn("value"); + QTest::addColumn("result_ok"); + QTest::addColumn("result"); + QTest::addColumn("event_count"); + + QTest::newRow("stdout cpp") + << "STDOUT_TARGET" << true << (int)ConsoleAppender::STDOUT_TARGET << 0; + QTest::newRow("stdout java") + << "System.out" << true << (int)ConsoleAppender::STDOUT_TARGET << 0; + QTest::newRow("stderr cpp") + << "STDERR_TARGET" << true << (int)ConsoleAppender::STDERR_TARGET << 0; + QTest::newRow("stderr java") + << "System.err" << true << (int)ConsoleAppender::STDERR_TARGET << 0; + QTest::newRow("trim") + << " STDOUT_TARGET " << true << (int)ConsoleAppender::STDOUT_TARGET << 0; + QTest::newRow("error") + << "Hello" << false << (int)ConsoleAppender::STDOUT_TARGET << 1; +} + + +void Log4QtTest::OptionConverter_target() +{ + QFETCH(QString, value); + QFETCH(bool, result_ok); + QFETCH(int, result); + QFETCH(int, event_count); + + mpLoggingEvents->clearList(); + bool ok; + QCOMPARE(OptionConverter::toTarget(value, &ok), result); + QCOMPARE(ok, result_ok); + QCOMPARE(mpLoggingEvents->list().count(), event_count); +} + + + +/****************************************************************************** + * Factory requires OptionConverter */ + + +void Log4QtTest::Factory_createAppender_data() +{ + QTest::addColumn("classname"); + QTest::addColumn("result"); + QTest::addColumn("event_count"); + + QTest::newRow("ConsoleAppender java") + << "org.apache.log4j.ConsoleAppender" << "Log4Qt::ConsoleAppender" << 0; + QTest::newRow("ConsoleAppender cpp") + << "Log4Qt::ConsoleAppender" << "Log4Qt::ConsoleAppender" << 0; + QTest::newRow("DailyRollingFileAppender java") + << "org.apache.log4j.DailyRollingFileAppender" << "Log4Qt::DailyRollingFileAppender" << 0; + QTest::newRow("DailyRollingFileAppender cpp") + << "Log4Qt::DailyRollingFileAppender" << "Log4Qt::DailyRollingFileAppender" << 0; + QTest::newRow("DebugAppender java") + << "org.apache.log4j.varia.DebugAppender" << "Log4Qt::DebugAppender" << 0; + QTest::newRow("DebugAppender cpp") + << "Log4Qt::DebugAppender" << "Log4Qt::DebugAppender" << 0; + QTest::newRow("FileAppender java") + << "org.apache.log4j.FileAppender" << "Log4Qt::FileAppender" << 0; + QTest::newRow("FileAppender cpp") + << "Log4Qt::FileAppender" << "Log4Qt::FileAppender" << 0; + QTest::newRow("ListAppender java") + << "org.apache.log4j.varia.ListAppender" << "Log4Qt::ListAppender" << 0; + QTest::newRow("ListAppender cpp") + << "Log4Qt::ListAppender" << "Log4Qt::ListAppender" << 0; + QTest::newRow("NullAppender java") + << "org.apache.log4j.varia.NullAppender" << "Log4Qt::NullAppender" << 0; + QTest::newRow("NullAppender cpp") + << "Log4Qt::NullAppender" << "Log4Qt::NullAppender" << 0; + QTest::newRow("RollingFileAppender java") + << "org.apache.log4j.RollingFileAppender" << "Log4Qt::RollingFileAppender" << 0; + QTest::newRow("RollingFileAppender cpp") + << "Log4Qt::RollingFileAppender" << "Log4Qt::RollingFileAppender" << 0; +} + + +void Log4QtTest::Factory_createAppender() +{ + QFETCH(QString, classname); + QFETCH(QString, result); + QFETCH(int, event_count); + + mpLoggingEvents->clearList(); + QObject *p_object = Factory::createAppender(classname); + QVERIFY(p_object != 0); + QCOMPARE(QString::fromLatin1(p_object->metaObject()->className()), result); + delete p_object; + QCOMPARE(mpLoggingEvents->list().count(), event_count); +} + + +void Log4QtTest::Factory_createFilter_data() +{ + QTest::addColumn("classname"); + QTest::addColumn("result"); + QTest::addColumn("event_count"); + + QTest::newRow("DenyAllFilter java") + << "org.apache.log4j.varia.DenyAllFilter" << "Log4Qt::DenyAllFilter" << 0; + QTest::newRow("DenyAllFilter cpp") + << "Log4Qt::DenyAllFilter" << "Log4Qt::DenyAllFilter" << 0; + QTest::newRow("LevelMatchFilter java") + << "org.apache.log4j.varia.LevelMatchFilter" << "Log4Qt::LevelMatchFilter" << 0; + QTest::newRow("LevelMatchFilter cpp") + << "Log4Qt::LevelMatchFilter" << "Log4Qt::LevelMatchFilter" << 0; + QTest::newRow("LevelRangeFilter java") + << "org.apache.log4j.varia.LevelRangeFilter" << "Log4Qt::LevelRangeFilter" << 0; + QTest::newRow("LevelRangeFilter cpp") + << "Log4Qt::LevelRangeFilter" << "Log4Qt::LevelRangeFilter" << 0; + QTest::newRow("StringMatchFilter java") + << "org.apache.log4j.varia.StringMatchFilter" << "Log4Qt::StringMatchFilter" << 0; + QTest::newRow("StringMatchFilter cpp") + << "Log4Qt::StringMatchFilter" << "Log4Qt::StringMatchFilter" << 0; +} + + +void Log4QtTest::Factory_createFilter() +{ + QFETCH(QString, classname); + QFETCH(QString, result); + QFETCH(int, event_count); + + mpLoggingEvents->clearList(); + QObject *p_object = Factory::createFilter(classname); + QVERIFY(p_object != 0); + QCOMPARE(QString::fromLatin1(p_object->metaObject()->className()), result); + delete p_object; + QCOMPARE(mpLoggingEvents->list().count(), event_count); +} + + +void Log4QtTest::Factory_createLayout_data() +{ + QTest::addColumn("classname"); + QTest::addColumn("result"); + QTest::addColumn("event_count"); + + QTest::newRow("PatternLayout java") + << "org.apache.log4j.PatternLayout" << "Log4Qt::PatternLayout" << 0; + QTest::newRow("PatternLayout cpp") + << "Log4Qt::PatternLayout" << "Log4Qt::PatternLayout" << 0; + QTest::newRow("SimpleLayout java") + << "org.apache.log4j.SimpleLayout" << "Log4Qt::SimpleLayout" << 0; + QTest::newRow("SimpleLayout cpp") + << "Log4Qt::SimpleLayout" << "Log4Qt::SimpleLayout" << 0; + QTest::newRow("TTCCLayout java") + << "org.apache.log4j.TTCCLayout" << "Log4Qt::TTCCLayout" << 0; + QTest::newRow("TTCCLayout cpp") + << "Log4Qt::TTCCLayout" << "Log4Qt::TTCCLayout" << 0; +} + + +void Log4QtTest::Factory_createLayout() +{ + QFETCH(QString, classname); + QFETCH(QString, result); + QFETCH(int, event_count); + + mpLoggingEvents->clearList(); + QObject *p_object = Factory::createLayout(classname); + QVERIFY(p_object != 0); + QCOMPARE(QString::fromLatin1(p_object->metaObject()->className()), result); + delete p_object; + QCOMPARE(mpLoggingEvents->list().count(), event_count); +} + + +void Log4QtTest::Factory_setObjectProperty_data() +{ + QTest::addColumn("appenderclass"); + QTest::addColumn("property"); + QTest::addColumn("value"); + QTest::addColumn("result_value"); + QTest::addColumn("event_count"); + + QTest::newRow("Bool") + << "Log4Qt::FileAppender" + << "immediateFlush" << "false" + << "false" << 0; + QTest::newRow("Int") + << "Log4Qt::ListAppender" + << "maxCount" << "10" + << "10" << 0; + QTest::newRow("QString") + << "Log4Qt::FileAppender" + << "file" << "C:\\tmp\\mylog.txt" + << "C:\\tmp\\mylog.txt" << 0; + QTest::newRow("Null object") + << "Log4Qt::NullAppender" + << "maxCount" << "10" + << "" << 1; + QTest::newRow("Empty property string") + << "Log4Qt::NullAppender" + << "" << "10" + << "" << 1; + QTest::newRow("Property does not exist") + << "Log4Qt::NullAppender" + << "Colour" << "10" + << "" << 1; + QTest::newRow("Property not writable") + << "Log4Qt::NullAppender" + << "isClosed" << "10" + << "" << 1; + QTest::newRow("Property of wrong type") + << "Log4Qt::RollingFileAppender" + << "maximumFileSize" << "7" + << "" << 1; +} + + +void Log4QtTest::Factory_setObjectProperty() +{ + QFETCH(QString, appenderclass); + QFETCH(QString, property); + QFETCH(QString, value); + QFETCH(QString, result_value); + QFETCH(int, event_count); + + mpLoggingEvents->clearList(); + QObject *p_object = Factory::createAppender(appenderclass); + + Factory::setObjectProperty(p_object, property, value); + QCOMPARE(mpLoggingEvents->list().count(), event_count); + if (mpLoggingEvents->list().count() == 0) + QCOMPARE(p_object->property(property.toLatin1()).toString(), result_value); + + delete p_object; +} + + + +/****************************************************************************** + * log4qt/varia */ + + +void Log4QtTest::ListAppender() +{ + Log4Qt::ListAppender appender; + + // Store messages + QCOMPARE(appender.list().count(), 0); + appender.doAppend(LoggingEvent(test_logger(), Level::WARN_INT, "Message1")); + appender.doAppend(LoggingEvent(test_logger(), Level::WARN_INT, "Message2")); + appender.doAppend(LoggingEvent(test_logger(), Level::WARN_INT, "Message3")); + QCOMPARE(appender.list().count(), 3); + + // Delete oldest, if max is set + appender.setMaxCount(2); + QCOMPARE(appender.list().count(), 2); + QCOMPARE(appender.list().at(0).message(), QString("Message2")); + QCOMPARE(appender.list().at(1).message(), QString("Message3")); + + // Ignore new ones added + appender.doAppend(LoggingEvent(test_logger(), Level::WARN_INT, "Message4")); + QCOMPARE(appender.list().count(), 2); + QCOMPARE(appender.list().at(0).message(), QString("Message2")); + QCOMPARE(appender.list().at(1).message(), QString("Message3")); + + // Clear + appender.clearList(); + QCOMPARE(appender.list().count(), 0); +} + + +void Log4QtTest::DenyAllFilter() +{ + Log4Qt::DenyAllFilter filter; + LoggingEvent event(test_logger(), Level::WARN_INT, "Message"); + QCOMPARE(filter.decide(event), Filter::DENY); +} + + +void Log4QtTest::LevelMatchFilter_data() +{ + QTest::addColumn("filter_level"); + QTest::addColumn("accept_on_match"); + QTest::addColumn("event_level"); + QTest::addColumn("result"); + + QTest::newRow("No match, No accept") << "WARN" << false << "TRACE" << "NEUTRAL"; + QTest::newRow("No match, Accept") << "WARN" << true << "TRACE" << "NEUTRAL"; + QTest::newRow("Match, No accept") << "WARN" << false << "WARN" << "DENY"; + QTest::newRow("Match, Accept") << "WARN" << true << "WARN" << "ACCEPT"; +} + + +void Log4QtTest::LevelMatchFilter() +{ + QFETCH(QString, filter_level); + QFETCH(bool, accept_on_match); + QFETCH(QString, event_level); + QFETCH(QString, result); + + Log4Qt::LevelMatchFilter filter; + filter.setLevelToMatch(Level::fromString(filter_level)); + filter.setAcceptOnMatch(accept_on_match); + LoggingEvent + event(test_logger(), Level::fromString(event_level), + "Message"); + + QString decision = + enumValueToKey(&filter, "Decision", filter.decide(event)); + QCOMPARE(decision, result); +} + + +void Log4QtTest::LevelRangeFilter_data() +{ + QTest::addColumn("filter_min_level"); + QTest::addColumn("filter_max_level"); + QTest::addColumn("accept_on_match"); + QTest::addColumn("event_level"); + QTest::addColumn("result"); + + QTest::newRow("Too low, No accept") << "DEBUG" << "ERROR" << false << "TRACE" << "DENY"; + QTest::newRow("Too high, No accept") << "DEBUG" << "ERROR" << false << "FATAL" << "DENY"; + QTest::newRow("Min, No accept") << "DEBUG" << "ERROR" << false << "DEBUG" << "NEUTRAL"; + QTest::newRow("Inside, No accept") << "DEBUG" << "ERROR" << false << "WARN" << "NEUTRAL"; + QTest::newRow("Max, No accept") << "DEBUG" << "ERROR" << false << "ERROR" << "NEUTRAL"; + QTest::newRow("Min not initialised, No accept") << "" << "ERROR" << false << "TRACE" << "NEUTRAL"; + QTest::newRow("Max not initialised, No accept") << "DEBUG" << "" << false << "FATAL" << "NEUTRAL"; + QTest::newRow("Too low, Accept") << "DEBUG" << "ERROR" << true << "TRACE" << "DENY"; + QTest::newRow("Too high, Accept") << "DEBUG" << "ERROR" << true << "FATAL" << "DENY"; + QTest::newRow("Min, Accept") << "DEBUG" << "ERROR" << true << "DEBUG" << "ACCEPT"; + QTest::newRow("Inside, Accept") << "DEBUG" << "ERROR" << true << "WARN" << "ACCEPT"; + QTest::newRow("Max, Accept") << "DEBUG" << "ERROR" << true << "ERROR" << "ACCEPT"; + QTest::newRow("Min not initialised, Accept") << "" << "ERROR" << true << "TRACE" << "ACCEPT"; + QTest::newRow("Max not initialised, Accept") << "DEBUG" << "" << true << "FATAL" << "ACCEPT"; +} + + +void Log4QtTest::LevelRangeFilter() +{ + QFETCH(QString, filter_min_level); + QFETCH(QString, filter_max_level); + QFETCH(bool, accept_on_match); + QFETCH(QString, event_level); + QFETCH(QString, result); + + Log4Qt::LevelRangeFilter filter; + if (!filter_min_level.isEmpty()) + filter.setLevelMin(Level::fromString(filter_min_level)); + if (!filter_max_level.isEmpty()) + filter.setLevelMax(Level::fromString(filter_max_level)); + filter.setAcceptOnMatch(accept_on_match); + LoggingEvent + event(test_logger(), Level::fromString(event_level), + "Message"); + + QString decision = + enumValueToKey(&filter, "Decision", filter.decide(event)); + QCOMPARE(decision, result); +} + + +void Log4QtTest::StringMatchFilter_data() +{ + QTest::addColumn("filter_string"); + QTest::addColumn("accept_on_match"); + QTest::addColumn("event_string"); + QTest::addColumn("result"); + + QTest::newRow("No match, No accept") << "MESSAGE" << false << "This is a message" << "NEUTRAL"; + QTest::newRow("Match, No accept") << "This" << false << "This is a message" << "DENY"; + QTest::newRow("No match, Accept") << "MESSAGE" << true << "This is a message" << "NEUTRAL"; + QTest::newRow("Match, Accept") << "This" << true << "This is a message" << "ACCEPT"; + QTest::newRow("Empty message, No accept") << "This" << false << "" << "NEUTRAL"; + QTest::newRow("Empty message, Accept") << "This" << true << "" << "NEUTRAL"; + QTest::newRow("Empty filter, No accept") << "" << false << "This is a message" << "NEUTRAL"; + QTest::newRow("Empty filter, Accept") << "" << true << "This is a message" << "NEUTRAL"; +} + + +void Log4QtTest::StringMatchFilter() +{ + QFETCH(QString, filter_string); + QFETCH(bool, accept_on_match); + QFETCH(QString, event_string); + QFETCH(QString, result); + + Log4Qt::StringMatchFilter filter; + filter.setStringToMatch(filter_string); + filter.setAcceptOnMatch(accept_on_match); + LoggingEvent event(test_logger(), Level::WARN_INT, event_string); + + QString decision = + enumValueToKey(&filter, "Decision", filter.decide(event)); + QCOMPARE(decision, result); +} + + + +/****************************************************************************** + * log4qt */ + + +void Log4QtTest::AppenderSkeleton_threshold() +{ + resetLogging(); + + Log4Qt::ListAppender *p_appender = new Log4Qt::ListAppender(); + Log4Qt::Logger *p_logger = test_logger(); + p_logger->addAppender(p_appender); + + // Threshold + p_appender->setThreshold(Level::ERROR_INT); + p_appender->doAppend(LoggingEvent(p_logger, Level::WARN_INT, "Warn")); + p_appender->doAppend(LoggingEvent(p_logger, Level::ERROR_INT, "Error")); + p_appender->doAppend(LoggingEvent(p_logger, Level::FATAL_INT, "Fatal")); + QCOMPARE(p_appender->list().count(), 2); + QCOMPARE(p_appender->list().at(0).level(), Level(Level::ERROR_INT)); + QCOMPARE(p_appender->list().at(1).level(), Level(Level::FATAL_INT)); +} + + +void Log4QtTest::AppenderSkeleton_filter_data() +{ + resetLogging(); + + QTest::addColumn("filter1_level"); + QTest::addColumn("filter1_accept"); + QTest::addColumn("filter2_level"); + QTest::addColumn("filter2_accept"); + QTest::addColumn("event_level"); + QTest::addColumn("event_count"); + + QTest::newRow("Single filter, NEUTRAL") + << "WARN" << true << "" << true << "TRACE" << 1; + QTest::newRow("Single filter, ACCEPT") + << "WARN" << true << "" << true << "WARN" << 1; + QTest::newRow("Single filter, DENY") + << "WARN" << false << "" << true << "WARN" << 0; + + QTest::newRow("Double filter, NEUTRAL NEUTRAL") + << "WARN" << true << "WARN" << true << "TRACE" << 1; + QTest::newRow("Double filter, NEUTRAL ACCEPT") + << "WARN" << true << "TRACE" << true << "TRACE" << 1; + QTest::newRow("Double filter, NEUTRAL DENY") + << "WARN" << true << "TRACE" << false << "TRACE" << 0; + + QTest::newRow("Double filter, ACCEPT NEUTRAL") + << "WARN" << true << "TRACE" << true << "WARN" << 1; + QTest::newRow("Double filter, ACCEPT ACCEPT") + << "WARN" << true << "WARN" << true << "WARN" << 1; + QTest::newRow("Double filter, ACCEPT DENY") + << "WARN" << true << "WARN" << false << "WARN" << 1; + + QTest::newRow("Double filter, DENY NEUTRAL") + << "WARN" << false << "TRACE" << true << "WARN" << 0; + QTest::newRow("Double filter, DENY ACCEPT") + << "WARN" << false << "WARN" << true << "WARN" << 0; + QTest::newRow("Double filter, DENY DENY") + << "WARN" << false << "WARN" << false << "WARN" << 0; +} + + +void Log4QtTest::AppenderSkeleton_filter() +{ + QFETCH(QString, filter1_level); + QFETCH(bool, filter1_accept); + QFETCH(QString, filter2_level); + QFETCH(bool, filter2_accept); + QFETCH(QString, event_level); + QFETCH(int, event_count); + + Log4Qt::ListAppender appender; + + if (!filter1_level.isEmpty()) + { + Log4Qt::LevelMatchFilter *p_filter = new Log4Qt::LevelMatchFilter(); + p_filter->setLevelToMatch(Level::fromString(filter1_level)); + p_filter->setAcceptOnMatch(filter1_accept); + appender.addFilter(p_filter); + } + if (!filter2_level.isEmpty()) + { + Log4Qt::LevelMatchFilter *p_filter = new Log4Qt::LevelMatchFilter(); + p_filter->setLevelToMatch(Level::fromString(filter2_level)); + p_filter->setAcceptOnMatch(filter2_accept); + appender.addFilter(p_filter); + } + + appender.doAppend(LoggingEvent(test_logger(), + Level::fromString(event_level), "Message")); + QCOMPARE(appender.list().count(), event_count); +} + + +void Log4QtTest::BasicConfigurator() +{ + LogManager::resetConfiguration(); + resetLogging(); + QVERIFY(Log4Qt::BasicConfigurator::configure()); + + Logger *p_logger = LogManager::rootLogger(); + QCOMPARE(p_logger->appenders().count(), 1); + ConsoleAppender *p_appender = + qobject_cast(p_logger->appenders().at(0)); + QCOMPARE(p_appender != 0, true); + QVERIFY(p_appender->isActive()); + QVERIFY(!p_appender->isClosed()); + QCOMPARE(p_appender->target(), QString::fromLatin1("STDOUT_TARGET")); + PatternLayout *p_layout = + qobject_cast(p_appender->layout()); + QVERIFY(p_layout != 0); + QCOMPARE(p_layout->conversionPattern(), QString("%r [%t] %p %c %x - %m%n")); + + // Log4Qt::Logger *logger = LogManager::rootLogger(); + // logger->trace("Trace message"); //Disabled by default + // logger->debug("Debug message"); + // logger->info("Info message"); + // logger->warn("Warn message"); + // logger->error("Error message"); + // logger->fatal("Fatal message"); +} + + +void Log4QtTest::FileAppender() +{ + resetLogging(); + + QString dir(mTemporaryDirectory.path() + "/FileAppender"); + QString file("/log"); + + Log4Qt::FileAppender appender1(new SimpleLayout(), dir + file, false); + appender1.setName("Fileappender1"); + appender1.activateOptions(); + appender1.doAppend(LoggingEvent(test_logger(), Level::DEBUG_INT, + QString("Message 0"))); + appender1.doAppend(LoggingEvent(test_logger(), Level::DEBUG_INT, + QString("Message 1"))); + appender1.close(); + QStringList expected; + QString result; + expected << "log"; + if (!validateDirContents(dir, expected, result)) + QFAIL(qPrintable(result)); + expected.clear(); + expected << "DEBUG - Message 0" << "DEBUG - Message 1"; + if (!validateFileContents(dir + file, expected, result)) + QFAIL(qPrintable(result)); + + Log4Qt::FileAppender appender2(new SimpleLayout(), dir + file, false); + appender2.setName("Fileappender2"); + appender2.activateOptions(); + appender2.doAppend(LoggingEvent(test_logger(), Level::DEBUG_INT, + QString("Message 2"))); + appender2.doAppend(LoggingEvent(test_logger(), Level::DEBUG_INT, + QString("Message 3"))); + appender2.close(); + expected.clear(); + expected << "log"; + if (!validateDirContents(dir, expected, result)) + QFAIL(qPrintable(result)); + expected.clear(); + expected << "DEBUG - Message 2" << "DEBUG - Message 3"; + if (!validateFileContents(dir + file, expected, result)) + QFAIL(qPrintable(result)); + + Log4Qt::FileAppender appender3(new SimpleLayout(), dir + file, true); + appender3.setName("Fileappender3"); + appender3.activateOptions(); + appender3.doAppend(LoggingEvent(test_logger(), Level::DEBUG_INT, + QString("Message 4"))); + appender3.doAppend(LoggingEvent(test_logger(), Level::DEBUG_INT, + QString("Message 5"))); + appender3.close(); + expected.clear(); + expected << "log"; + if (!validateDirContents(dir, expected, result)) + QFAIL(qPrintable(result)); + expected.clear(); + expected + << "DEBUG - Message 2" << "DEBUG - Message 3" + << "DEBUG - Message 4" << "DEBUG - Message 5"; + if (!validateFileContents(dir + file, expected, result)) + QFAIL(qPrintable(result)); + + QCOMPARE(mpLoggingEvents->list().count(), 0); +} + + +void Log4QtTest::DailyRollingFileAppender() +{ + resetLogging(); + + if (mSkipLongTests) +#if (QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)) + QSKIP("Skipping long running test"); +#else + QSKIP("Skipping long running test", SkipSingle); +#endif + qDebug() << "The test is time based and takes approximately 3 minutes ..."; + + QString dir(mTemporaryDirectory.path() + "/DailyRollingFileAppender"); + QString file("/log"); + + // Using a RollingFileAppender with 2 files history and 3 messages per file + Log4Qt::DailyRollingFileAppender appender; + appender.setName("DailyRollingFileAppender"); + appender.setFile(dir + file); + appender.setLayout(new SimpleLayout()); + appender.setDatePattern(DailyRollingFileAppender::MINUTELY_ROLLOVER); + + // Start on a full minute + QDateTime now = QDateTime::currentDateTime(); + QTest::qSleep((60 - now.time().second()) * 1000); + appender.activateOptions(); + + qDebug() << " 1 / 7"; + appender.doAppend(LoggingEvent(test_logger(), Level::DEBUG_INT, + QString("Message 0"))); + int i; + for (i = 1; i < 7; i++) + { + QTest::qSleep(21 * 1000); + qDebug() << " " << i + 1 << "/" << 7; + appender.doAppend(LoggingEvent(test_logger(), Level::DEBUG_INT, + QString("Message %1").arg(i))); + } + + QCOMPARE(mpLoggingEvents->list().count(), 0); + + // Validate directory + QStringList expected; + QString result; + expected << "log" << "log" + + dailyRollingFileAppenderSuffix(now.addSecs(60)) << "log" + + dailyRollingFileAppenderSuffix(now.addSecs(120)); + if (!validateDirContents(dir, expected, result)) + QFAIL(qPrintable(result)); + + // Validate files + expected.clear(); + expected << "DEBUG - Message 6"; + if (!validateFileContents(dir + file, expected, result)) + QFAIL(qPrintable(result)); + expected.clear(); + expected << "DEBUG - Message 0" << "DEBUG - Message 1" + << "DEBUG - Message 2"; + if (!validateFileContents(dir + file + + dailyRollingFileAppenderSuffix(now.addSecs(60)), + expected, result)) + QFAIL(qPrintable(result)); + expected.clear(); + expected << "DEBUG - Message 3" << "DEBUG - Message 4" + << "DEBUG - Message 5"; + if (!validateFileContents(dir + file + + dailyRollingFileAppenderSuffix(now.addSecs(120)), + expected, result)) + QFAIL(qPrintable(result)); +} + + +void Log4QtTest::LoggingEvent_stream_data() +{ + QTest::addColumn("original"); + + qint64 timestamp = + DateTime(QDateTime(QDate(2001,9,7), QTime(15,7,5,9))).toMilliSeconds(); + QHash properties; + properties.insert("A", "a"); + properties.insert("B", "b"); + properties.insert("C", "c"); + + QTest::newRow("Empty logging event") + << LoggingEvent(); + QTest::newRow("Logging event") + << LoggingEvent(test_logger(), + Level(Level::WARN_INT), + "This is a message", + "NDC", + properties, + "main", + timestamp); + QTest::newRow("Logging no logger") + << LoggingEvent(0, + Level(Level::WARN_INT), + "This is a message", + "NDC", + properties, + "main", + timestamp); + + resetLogging(); +} + + +void Log4QtTest::LoggingEvent_stream() +{ + QFETCH(LoggingEvent, original); + + QByteArray array; + QBuffer buffer(&array); + buffer.open(QIODevice::WriteOnly); + QDataStream stream(&buffer); + stream << original; + buffer.close(); + + buffer.open(QIODevice::ReadOnly); + LoggingEvent streamed; + stream >> streamed; + buffer.close(); + + QCOMPARE(original.level(), streamed.level()); + QCOMPARE(original.loggerName(), streamed.loggerName()); + QCOMPARE(original.message(), streamed.message()); + QCOMPARE(original.ndc(), streamed.ndc()); + QCOMPARE(original.properties().count(), streamed.properties().count()); + QStringList keys = original.properties().keys(); + QString key; + Q_FOREACH(key, keys) + { + QVERIFY(streamed.properties().contains(key)); + QCOMPARE(original.properties().value(key), + streamed.properties().value(key)); + } + QCOMPARE(original.sequenceNumber(), streamed.sequenceNumber()); + QCOMPARE(original.threadName(), streamed.threadName()); + QCOMPARE(original.timeStamp(), streamed.timeStamp()); + + QCOMPARE(mpLoggingEvents->list().count(), 0); +} + + +void Log4QtTest::LogManager_configureLogLogger() +{ + resetLogging(); + LogManager::logLogger()->removeAppender(mpLoggingEvents); + + LogManager::resetConfiguration(); + Log4Qt::Logger *p_logger = LogManager::logLogger(); + QCOMPARE(p_logger->appenders().count(), 2); + ConsoleAppender *p_appender; + TTCCLayout *p_layout; + + p_appender = qobject_cast(p_logger->appenders().at(0)); + QCOMPARE(p_appender != 0, true); + QVERIFY(p_appender->isActive()); + QVERIFY(!p_appender->isClosed()); + QCOMPARE(p_appender->target(), QString::fromLatin1("STDOUT_TARGET")); + p_layout = qobject_cast(p_appender->layout()); + QVERIFY(p_layout != 0); + + p_appender = qobject_cast(p_logger->appenders().at(1)); + QCOMPARE(p_appender != 0, true); + QVERIFY(p_appender->isActive()); + QVERIFY(!p_appender->isClosed()); + QCOMPARE(p_appender->target(), QString::fromLatin1("STDERR_TARGET")); + p_layout = qobject_cast(p_appender->layout()); + QVERIFY(p_layout != 0); + +} + + +void Log4QtTest::PropertyConfigurator_missing_appender() +{ + LogManager::resetConfiguration(); + resetLogging(); + mDefaultProperties.clear(); + mProperties.clear(); + + mProperties.setProperty("log4j.logger.MissingAppender", + "INHERITED, A"); + QVERIFY(!PropertyConfigurator::configure(mProperties)); + QCOMPARE(ConfiguratorHelper::configureError().count(), 1); + QCOMPARE(mpLoggingEvents->list().count(), 1); +} + + +void Log4QtTest::PropertyConfigurator_unknown_appender_class() +{ + LogManager::resetConfiguration(); + resetLogging(); + mDefaultProperties.clear(); + mProperties.clear(); + + mProperties.setProperty("log4j.logger.UnknownAppender", + "INHERITED, A"); + mProperties.setProperty("log4j.appender.A", + "org.apache.log4j.UnknownAppender"); + QVERIFY(!PropertyConfigurator::configure(mProperties)); + QCOMPARE(ConfiguratorHelper::configureError().count(), 1); + QCOMPARE(mpLoggingEvents->list().count(), 2); // Warning from Factory, Error PropertyConfigurator +} + + +void Log4QtTest::PropertyConfigurator_missing_layout() +{ + resetLogging(); + mDefaultProperties.clear(); + mProperties.clear(); + + mProperties.setProperty("log4j.logger.MissingLayout", + "INHERITED, A"); + mProperties.setProperty("log4j.appender.A", + "org.apache.log4j.ConsoleAppender"); + QVERIFY(!PropertyConfigurator::configure(mProperties)); + QCOMPARE(ConfiguratorHelper::configureError().count(), 1); + QCOMPARE(mpLoggingEvents->list().count(), 1); +} + + +void Log4QtTest::PropertyConfigurator_unknown_layout_class() +{ + resetLogging(); + mDefaultProperties.clear(); + mProperties.clear(); + + mProperties.setProperty("log4j.logger.UnknownLayout", + "INHERITED, A"); + mProperties.setProperty("log4j.appender.A", + "org.apache.log4j.ConsoleAppender"); + mProperties.setProperty("log4j.appender.A.layout", + "org.apache.log4j.UnknownLayout"); + QVERIFY(!PropertyConfigurator::configure(mProperties)); + QCOMPARE(ConfiguratorHelper::configureError().count(), 1); + QCOMPARE(mpLoggingEvents->list().count(), 2); // Warning from Factory, Error PropertyConfigurator +} + + +void Log4QtTest::PropertyConfigurator_reset() +{ + resetLogging(); + mDefaultProperties.clear(); + mProperties.clear(); + + // - Create a logger with an appender + // - If the reset flag is not set, configure must leave the appender + // - If the reset flag is set to an invalid value, configure must raise an + // error and leave the appender + // - If the reset flag is set, configure must remove the appender + + const QLatin1String key_reset("log4j.reset"); + test_logger()->addAppender(new Log4Qt::ListAppender); + mProperties.setProperty(key_reset, + "false"); + QVERIFY(PropertyConfigurator::configure(mProperties)); + QCOMPARE(ConfiguratorHelper::configureError().count(), 0); + QCOMPARE(mpLoggingEvents->list().count(), 0); + QCOMPARE(test_logger()->appenders().count(), 1); + + mProperties.setProperty(key_reset, + "No boolean"); + QVERIFY(!PropertyConfigurator::configure(mProperties)); + QCOMPARE(ConfiguratorHelper::configureError().count(), 1); + QCOMPARE(mpLoggingEvents->list().count(), 1); + QCOMPARE(test_logger()->appenders().count(), 1); + + resetLogging(); + mProperties.setProperty(key_reset, + "true"); + QVERIFY(PropertyConfigurator::configure(mProperties)); + QCOMPARE(ConfiguratorHelper::configureError().count(), 0); + QCOMPARE(mpLoggingEvents->list().count(), 0); + QCOMPARE(test_logger()->appenders().count(), 0); +} + + +void Log4QtTest::PropertyConfigurator_debug() +{ + resetLogging(); + mDefaultProperties.clear(); + mProperties.clear(); + + // - Set the log logger level to INFO + // - If debug is not set, configure must leave the log logger level + // unaltered + // - If debug is set, but with no valid level string, configure must set + // the log logger level to DEBUG + // - If debug is set to the level TRACE, configure must set the log logger + // level to TRACE + + const QLatin1String key_debug("log4j.Debug"); + Logger *p_logger = LogManager::logLogger(); + p_logger->setLevel(Level::INFO_INT); + + QVERIFY(PropertyConfigurator::configure(mProperties)); + QCOMPARE(ConfiguratorHelper::configureError().count(), 0); + QCOMPARE(mpLoggingEvents->list().count(), 0); + QCOMPARE(p_logger->level(), Level(Level::INFO_INT)); + + mProperties.setProperty(key_debug, + "true"); + QVERIFY(PropertyConfigurator::configure(mProperties)); + QCOMPARE(ConfiguratorHelper::configureError().count(), 0); + // QCOMPARE(mpLoggingEvents->list().count(), 1); // Warning from Level::fromString() & several debug messages + QCOMPARE(p_logger->level(), Level(Level::DEBUG_INT)); + + mpLoggingEvents->clearList(); + mProperties.setProperty(key_debug, + "TRACE"); + QVERIFY(PropertyConfigurator::configure(mProperties)); + QCOMPARE(ConfiguratorHelper::configureError().count(), 0); + // QCOMPARE(mpLoggingEvents->list().count(), 1); // Warning from PropertyConfigurator & several debug/trace messages + QCOMPARE(p_logger->level(), Level(Level::TRACE_INT)); +} + + +void Log4QtTest::PropertyConfigurator_threshold() +{ + resetLogging(); + mDefaultProperties.clear(); + mProperties.clear(); + + // - Set the repository threshold to INFO + // - If the threshold is not set, configure must leave the repository + // threshold unaltered + // - If the threshold is set to an invalid value, configure must raise an + // error and set the threshold to ALL + // - If the threshold is set to WARN, configure must set the repository + // threshold to WARN + + const QLatin1String key_threshold("log4j.threshold"); + LogManager::loggerRepository()->setThreshold(Level::INFO_INT); + + QVERIFY(PropertyConfigurator::configure(mProperties)); + QCOMPARE(ConfiguratorHelper::configureError().count(), 0); + QCOMPARE(mpLoggingEvents->list().count(), 0); + QCOMPARE(LogManager::loggerRepository()->threshold(), Level(Level::INFO_INT)); + + mProperties.setProperty(key_threshold, + "Not a value"); + QVERIFY(!PropertyConfigurator::configure(mProperties)); + QCOMPARE(ConfiguratorHelper::configureError().count(), 1); + QCOMPARE(mpLoggingEvents->list().count(), 2); // Warning by Level, Error from OptionConverter + QCOMPARE(LogManager::loggerRepository()->threshold(), Level(Level::ALL_INT)); + + mpLoggingEvents->clearList(); + mProperties.setProperty(key_threshold, + "WARN"); + QVERIFY(PropertyConfigurator::configure(mProperties)); + QCOMPARE(ConfiguratorHelper::configureError().count(), 0); + QCOMPARE(mpLoggingEvents->list().count(), 0); + QCOMPARE(LogManager::loggerRepository()->threshold(), Level(Level::WARN_INT)); +} + + +void Log4QtTest::PropertyConfigurator_handleQtMessages() +{ + resetLogging(); + mDefaultProperties.clear(); + mProperties.clear(); + + // - Set handle Qt messages to true + // - If handle Qt messages is not set, configure must leave handle Qt + // messages unaltered + // - If handle Qt messages is set to an invalid value, configure must raise + // an error and set handle Qt messages to false + // - If handle Qt messages is true, configure must set handle Qt messages + // to true + + const QLatin1String key_handle_qt_messages("log4j.handleQtMessages"); + LogManager::setHandleQtMessages(true); + + QVERIFY(PropertyConfigurator::configure(mProperties)); + QCOMPARE(ConfiguratorHelper::configureError().count(), 0); + QCOMPARE(mpLoggingEvents->list().count(), 0); + QCOMPARE(LogManager::handleQtMessages(), true); + + mProperties.setProperty(key_handle_qt_messages, + "No boolean"); + QVERIFY(!PropertyConfigurator::configure(mProperties)); + QCOMPARE(ConfiguratorHelper::configureError().count(), 1); + QCOMPARE(mpLoggingEvents->list().count(), 1); + QCOMPARE(LogManager::handleQtMessages(), false); + + mpLoggingEvents->clearList(); + mProperties.setProperty(key_handle_qt_messages, + "true"); + QVERIFY(PropertyConfigurator::configure(mProperties)); + QCOMPARE(ConfiguratorHelper::configureError().count(), 0); + QCOMPARE(mpLoggingEvents->list().count(), 0); + QCOMPARE(LogManager::handleQtMessages(), true); +} + + +void Log4QtTest::PropertyConfigurator_example() +{ + LogManager::resetConfiguration(); + resetLogging(); + mDefaultProperties.clear(); + mProperties.clear(); + + QString file(mTemporaryDirectory.path() + "/RollingFileAppender/log"); + + // Based on the JavaDoc example: + // - A1: JavaDoc uses SyslogAppender, which is not available on all platforms + // - A2: JavaDoc does not set a file, which causes error on activation + // - A2: JavaDoc uses default values for file size and backup index. Use + // different values. + // - A2 Layout: ContextPrinting uses default enabled. Use disabled instead. + // - root: JavaDoc uses default level DEBUG. Use INFO instead. + // - SECURITY: JavaDoc uses INHERIT. Use INHERITED instead + // - log4j.logger.class.of.the.day: JavaDoc uses INHERIT. Use INHERITED + // instead + + // Appender A1: ConsoleAppender with PatternLayout + mProperties.setProperty("log4j.appender.A1", + "org.apache.log4j.ConsoleAppender"); + mProperties.setProperty("log4j.appender.A1.Target", "System.Out"); + mProperties.setProperty("log4j.appender.A1.layout", + "org.apache.log4j.PatternLayout"); + mProperties.setProperty("log4j.appender.A1.layout.ConversionPattern", + "%-4r %-5p %c{2} %M.%L %x - %m\n"); + // Appender A2: RollingFileAppender with TTCCLayout + mProperties.setProperty("log4j.appender.A2", + "org.apache.log4j.RollingFileAppender"); + mProperties.setProperty("log4j.appender.A2.File", file); + mProperties.setProperty("log4j.appender.A2.MaxFileSize", "13MB"); + mProperties.setProperty("log4j.appender.A2.MaxBackupIndex", "7"); + mProperties.setProperty("log4j.appender.A2.layout", + "org.apache.log4j.TTCCLayout"); + mProperties.setProperty("log4j.appender.A2.layout.ContextPrinting", + "disabled"); + mProperties.setProperty("log4j.appender.A2.layout.DateFormat", "ISO8601"); + // Root Logger: Uses A2 + mProperties.setProperty("log4j.rootLogger", "INFO, A2"); + // Logger SECURITY: Uses A1 + mProperties.setProperty("log4j.logger.SECURITY", "INHERITED, A1"); + mProperties.setProperty("log4j.additivity.SECURITY", "false"); + // Logger SECURITY.access: + mProperties.setProperty("log4j.logger.SECURITY.access", "WARN"); + // Logger class.of.the.day: + mProperties.setProperty("log4j.logger.class.of.the.day", "INHERITED"); + + // No warnings, no errors expected + QVERIFY(PropertyConfigurator::configure(mProperties)); + QCOMPARE(ConfiguratorHelper::configureError().count(), 0); + QCOMPARE(mpLoggingEvents->list().count(), 0); + + // Root logger + Logger *p_logger; + p_logger = LogManager::rootLogger(); + QCOMPARE(p_logger->level(), Level(Level::INFO_INT)); + QCOMPARE(p_logger->appenders().count(), 1); + Log4Qt::RollingFileAppender *p_a2 = + qobject_cast(p_logger->appenders().at(0)); + QVERIFY(p_a2 != 0); + QCOMPARE(p_a2->file(), file); + QCOMPARE(p_a2->maximumFileSize(), Q_INT64_C(13*1024*1024)); + QCOMPARE(p_a2->maxBackupIndex(), 7); + Log4Qt::TTCCLayout *p_a2layout = + qobject_cast(p_a2->layout()); + QVERIFY(p_a2layout != 0); + QCOMPARE(p_a2layout->contextPrinting(), false); + QCOMPARE(p_a2layout->dateFormat(), QString::fromLatin1("ISO8601")); + + // Logger SECURITY + QVERIFY(LogManager::exists("SECURITY")); + p_logger = LogManager::logger("SECURITY"); + QCOMPARE(p_logger->level(), Level(Level::NULL_INT)); + QCOMPARE(p_logger->appenders().count(), 1); + Log4Qt::ConsoleAppender *p_a1 = + qobject_cast(p_logger->appenders().at(0)); + QVERIFY(p_a1 != 0); + QCOMPARE(p_a1->target(), QString::fromLatin1("STDOUT_TARGET")); + Log4Qt::PatternLayout *p_a1layout = + qobject_cast(p_a1->layout()); + QVERIFY(p_a1layout != 0); + QCOMPARE(p_a1layout->conversionPattern(), QString::fromLatin1("%-4r %-5p %c{2} %M.%L %x - %m\n")); + + // Logger SECURITY::access + QVERIFY(LogManager::exists("SECURITY::access")); + p_logger = LogManager::logger("SECURITY::access"); + QCOMPARE(p_logger->level(), Level(Level::WARN_INT)); + + // Logger class::of::the::day + QVERIFY(LogManager::exists("class::of::the::day")); +} + + +void Log4QtTest::RollingFileAppender() +{ + resetLogging(); + + QString dir(mTemporaryDirectory.path() + "/RollingFileAppender"); + QString file("/log"); + + // Using a RollingFileAppender with 2 files history and 3 messages per file + Log4Qt::RollingFileAppender appender; + appender.setName("RollingFileAppender"); + appender.setFile(dir + file); + appender.setLayout(new SimpleLayout()); + appender.setMaxBackupIndex(2); + appender.setMaximumFileSize(40); + appender.activateOptions(); + + // Output 9 messages + int i; + for (i = 0; i < 10; i++) + appender.doAppend(LoggingEvent(test_logger(), Level::DEBUG_INT, + QString("Message %1").arg(i))); + + // No warnings or errors expected + QCOMPARE(mpLoggingEvents->list().count(), 0); + + // Validate diretcory + QStringList expected; + QString result; + expected << "log" << "log.1" << "log.2"; + if (!validateDirContents(dir, expected, result)) + QFAIL(qPrintable(result)); + + // Validate files + expected.clear(); + expected << "DEBUG - Message 9"; + if (!validateFileContents(dir + file, expected, result)) + QFAIL(qPrintable(result)); + expected.clear(); + expected << "DEBUG - Message 6" << "DEBUG - Message 7" + << "DEBUG - Message 8"; + if (!validateFileContents(dir + file + ".1", expected, result)) + QFAIL(qPrintable(result)); + expected.clear(); + expected << "DEBUG - Message 3" << "DEBUG - Message 4" + << "DEBUG - Message 5"; + if (!validateFileContents(dir + file + ".2", expected, result)) + QFAIL(qPrintable(result)); + + QCOMPARE(mpLoggingEvents->list().count(), 0); +} + + +QString Log4QtTest::dailyRollingFileAppenderSuffix(const QDateTime &rDateTime) +{ + QString result("."); + result += QString::number(rDateTime.date().year()).rightJustified(4, '0'); + result += '-'; + result += QString::number(rDateTime.date().month()).rightJustified(2, '0'); + result += '-'; + result += QString::number(rDateTime.date().day()).rightJustified(2, '0'); + result += '-'; + result += QString::number(rDateTime.time().hour()).rightJustified(2, '0'); + result += '-'; + result += QString::number(rDateTime.time().minute()).rightJustified(2, '0'); + return result; +} + + +QString Log4QtTest::enumValueToKey(QObject *pObject, + const char* pEnumeration, + int value) +{ + Q_ASSERT(pObject); + Q_ASSERT(!QString(pEnumeration).isEmpty()); + + int i = pObject->metaObject()->indexOfEnumerator(pEnumeration); + Q_ASSERT(i >= 0); + QMetaEnum enumerator = pObject->metaObject()->enumerator(i); + Q_ASSERT(enumerator.isValid()); + QString result = enumerator.valueToKey(value); + Q_ASSERT(!result.isNull()); + return result; +} + + +void Log4QtTest::resetLogging() +{ + Log4Qt::Logger *p_logger; + + // Log4Qt logger + p_logger = LogManager::logLogger(); + p_logger->setAdditivity(false); + p_logger->setLevel(Level::WARN_INT); + p_logger->removeAllAppenders(); + + // Log4QtTest appender + p_logger->addAppender(mpLoggingEvents); + mpLoggingEvents->clearList(); + mpLoggingEvents->clearFilters(); + mpLoggingEvents->setThreshold(Level::WARN_INT); + + // Test logger + p_logger = test_logger(); + p_logger->setAdditivity(true); + p_logger->setLevel(Level::NULL_INT); +} + + +bool Log4QtTest::compareStringLists(const QStringList &rActual, + const QStringList &rExpected, + const QString &rEntry, + const QString &rEntries, + QString &rResult) +{ + QString tab(" "); + QString eol("\n"); + + // Generate content string + QString content; + int i; + content += tab + "Actual: " + rEntries + ": " + + QString::number(rActual.count()) + eol; + for (i = 0; i < rActual.count(); i++) + content += tab + tab + '\'' + rActual.at(i) + '\'' + eol; + content += tab + "Expected: " + rEntries + ": " + + QString::number(rExpected.count()) + eol; + for (i = 0; i < rExpected.count(); i++) + content += tab + tab + '\'' + rExpected.at(i) + '\'' + eol; + + // Check count + if (rActual.count() != rExpected.count()) + { + rResult = tab + "Compared " + rEntry + " counts are not the same" + eol; + rResult += content; + return false; + } + + // Check entries + for (i = 0; i < rActual.count(); i++) + { + if (rActual.at(i) != rExpected.at(i)) + { + rResult = tab + rEntry + " " + QString::number(i + 1) + + " is not the same" + eol; + rResult += content; + return false; + } + } + + rResult.clear(); + return true; +} + + +bool Log4QtTest::deleteDirectoryTree(const QString &rName) +{ + QFileInfo file_info(rName); + if (!file_info.exists()) + return true; + if (file_info.isDir()) + { + QDir d(rName); + QStringList members = d.entryList(QDir::Dirs | QDir::Files + | QDir::NoDotAndDotDot | QDir::NoSymLinks + | QDir::Hidden, QDir::Name | QDir::DirsFirst); + QString member; + Q_FOREACH(member, members) + if (!deleteDirectoryTree(rName + '/' + member)) + return false; + if (d.rmdir(rName)) + return true; + qDebug() << "Unable to remove directory: " << rName; + return false; + } + else + { + QFile f(rName); + if (f.remove()) + return true; + qDebug() << "Unable to remove file: " << rName << "(" + << f.errorString() << ")"; + return false; + } +} + + +bool Log4QtTest::validateDirContents(const QString &rName, + const QStringList &rExpected, + QString &rResult) +{ + QDir dir(rName); + if (!dir.exists()) + { + rResult = QString("The dir '%1' does not exist").arg(rName); + return false; + } + + QStringList actual = dir.entryList(QDir::Dirs | QDir::Files + | QDir::NoDotAndDotDot | QDir::NoSymLinks | QDir::Hidden, + QDir::Name | QDir::DirsFirst); + if (!compareStringLists(actual, rExpected, "Entry", "Entries", rResult)) + { + QString error = + "The directory contents validation failed.\n '%1'\n%2"; + rResult = error.arg(rName, rResult); + return false; + } + + return true; +} + + +bool Log4QtTest::validateFileContents(const QString &rName, + const QStringList &rExpected, + QString &rResult) +{ + QFile file(rName); + if (!file.exists()) + { + rResult = QString("The expected file '%1' does not exist (%2)").arg(rName).arg(file.errorString()); + return false; + } + if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) + { + rResult = QString("The expected file '%1' cannot be opened (%2)").arg(rName).arg(file.errorString()); + return false; + } + + QStringList actual; + QTextStream textstream(&file); + QString line = textstream.readLine(); + while (!line.isNull()) + { + actual << line; + line = textstream.readLine(); + } + if (!compareStringLists(actual, rExpected, "Line", "Lines", rResult)) + { + QString error = "The file contents validation failed.\n '%1'\n%2"; + rResult = error.arg(rName, rResult); + return false; + } + + return true; +} + + + +/****************************************************************************** + * Implementation: Operators, Helper + ******************************************************************************/ + + diff --git a/src/log4qt/tests/log4qttest.h b/src/log4qt/tests/log4qttest.h new file mode 100644 index 0000000..dcddf3a --- /dev/null +++ b/src/log4qt/tests/log4qttest.h @@ -0,0 +1,177 @@ +/****************************************************************************** + * + * package: Log4Qt + * file: loggingtest.h + * created: September 2007 + * author: Martin Heinrich + * + * + * Copyright 2007 Martin Heinrich + * + * 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. + * + ******************************************************************************/ + +#ifndef LOG4QT_LOG4QTTEST_H +#define LOG4QT_LOG4QTTEST_H + + +/****************************************************************************** + * Dependencies + ******************************************************************************/ + +#include +#include + +#include "log4qt/helpers/properties.h" +#include "log4qt/logger.h" +#include "log4qt/varia/listappender.h" + + +/****************************************************************************** + * Declarations + ******************************************************************************/ + +/*! + * \brief The class Log4QtTest provides a unit test for the package Log4Qt. + * + * The class Log4QtTest implements a unit test based on th Qt testing framework. + */ +class Log4QtTest : public QObject +{ + Q_OBJECT + +public: + Log4QtTest(); + virtual ~Log4QtTest(); +private: + Log4QtTest(const Log4QtTest &rOther); // Not implemented + Log4QtTest &operator=(const Log4QtTest &rOther); // Not implemented + +private slots: + void initTestCase(); + void cleanupTestCase(); + + // log4qt/helpers + void DateTime_compability_data(); + void DateTime_compability(); + void DateTime_week_data(); + void DateTime_week(); + void DateTime_milliseconds_data(); + void DateTime_milliseconds(); + void PatternFormatter_data(); + void PatternFormatter(); + void Properties_default_data(); + void Properties_default(); + void Properties_names(); + void Properties_load_device_data(); + void Properties_load_device(); + void Properties_load_settings(); + + // OptionConverter requires Properties + void OptionConverter_boolean_data(); + void OptionConverter_boolean(); + void OptionConverter_filesize_data(); + void OptionConverter_filesize(); + void OptionConverter_int_data(); + void OptionConverter_int(); + void OptionConverter_level_data(); + void OptionConverter_level(); + void OptionConverter_substitution_data(); + void OptionConverter_substitution(); + void OptionConverter_target_data(); + void OptionConverter_target(); + + // Factory requires OptionConverter + void Factory_createAppender_data(); + void Factory_createAppender(); + void Factory_createFilter_data(); + void Factory_createFilter(); + void Factory_createLayout_data(); + void Factory_createLayout(); + void Factory_setObjectProperty_data(); + void Factory_setObjectProperty(); + + // log4qt/varia + void ListAppender(); + void DenyAllFilter(); + void LevelMatchFilter_data(); + void LevelMatchFilter(); + void LevelRangeFilter_data(); + void LevelRangeFilter(); + void StringMatchFilter_data(); + void StringMatchFilter(); + + // log4qt + void AppenderSkeleton_threshold(); + void AppenderSkeleton_filter_data(); + void AppenderSkeleton_filter(); + void BasicConfigurator(); + void FileAppender(); + void DailyRollingFileAppender(); + void LoggingEvent_stream_data(); + void LoggingEvent_stream(); + void LogManager_configureLogLogger(); + void PropertyConfigurator_missing_appender(); + void PropertyConfigurator_unknown_appender_class(); + void PropertyConfigurator_missing_layout(); + void PropertyConfigurator_unknown_layout_class(); + void PropertyConfigurator_reset(); + void PropertyConfigurator_debug(); + void PropertyConfigurator_threshold(); + void PropertyConfigurator_handleQtMessages(); + void PropertyConfigurator_example(); + void RollingFileAppender(); + +private: + QString dailyRollingFileAppenderSuffix(const QDateTime &rDateTime); + QString enumValueToKey(QObject *pObject, + const char* pEnumeration, + int value); + void resetLogging(); + static bool compareStringLists(const QStringList &rActual, + const QStringList &rExpected, + const QString &rEntry, + const QString &rEntries, + QString &rResult); + static bool deleteDirectoryTree(const QString &rName); + static bool validateDirContents(const QString &rName, + const QStringList &rExpected, + QString &rResult); + static bool validateFileContents(const QString &rName, + const QStringList &rExpected, + QString &rResult); + +private: + bool mSkipLongTests; + QDir mTemporaryDirectory; + Log4Qt::ListAppender *mpLoggingEvents; + Log4Qt::Properties mDefaultProperties; + Log4Qt::Properties mProperties; +}; + + +/****************************************************************************** + * Operators, Helper + ******************************************************************************/ + + +/****************************************************************************** + * Inline + ******************************************************************************/ + + +// Q_DECLARE_TYPEINFO(Log4Qt::Log4QtTest, Q_COMPLEX_TYPE); // use default + + +#endif // LOG4QT_LOG4QTTEST_H diff --git a/src/log4qt/tests/log4qttest.pro b/src/log4qt/tests/log4qttest.pro new file mode 100644 index 0000000..16fe8a6 --- /dev/null +++ b/src/log4qt/tests/log4qttest.pro @@ -0,0 +1,42 @@ +# ******************************************************************************* +# +# package: Log4Qt +# file: log4qttest.pro +# created: September 2007 +# author: Martin Heinrich +# +# +# Copyright 2007 Martin Heinrich +# +# 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. +# +# ******************************************************************************* + +TEMPLATE = app + +isEqual(QT_MAJOR_VERSION, 5) { + QT += testlib +} else { # if not Qt5 + CONFIG += qtestlib +} + +DEFINES -= \ + QT_NO_CAST_FROM_ASCII \ + QT_NO_CAST_TO_ASCII + +include(../src/log4qt/log4qt.pri) + +HEADERS += log4qttest.h +SOURCES += log4qttest.cpp + + diff --git a/src/log4qt/ukui-log4qt.cpp b/src/log4qt/ukui-log4qt.cpp new file mode 100644 index 0000000..a87be26 --- /dev/null +++ b/src/log4qt/ukui-log4qt.cpp @@ -0,0 +1,40 @@ +/* + * Copyright (C) 2021 Tianjin KYLIN Information Technology Co., Ltd. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see + +#include "ukui-logconfigurator.h" + +// 初始化ukui-log4qt库,传入application名称 +int initUkuiLog4qt(QString strAppName) +{ + if (strAppName.isEmpty()){ + return -1; + } + // 检查纠正名称格式 小写+'-'+数字 + strAppName = strAppName.toLower(); + // 非数字和小写字母以'-'代替 + strAppName.replace(QRegExp("[^a-z0-9]+"),"-"); + // 多个'-'以一个'-'代替 + strAppName.replace(QRegExp("[-]+"),"-"); + // 去掉头部的非字母串和尾部的'-'’ + strAppName.replace(QRegExp("(^[^a-z]+|-$)"),""); + // 初始化log4qt配置 + return UkuiLog4qtConfig::instance()->init(strAppName); +} diff --git a/src/log4qt/ukui-log4qt.h b/src/log4qt/ukui-log4qt.h new file mode 100644 index 0000000..5744586 --- /dev/null +++ b/src/log4qt/ukui-log4qt.h @@ -0,0 +1,42 @@ +/* + * Copyright (C) 2021 Tianjin KYLIN Information Technology Co., Ltd. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see + +//输出debug级别日志 +#define KyDebug QMessageLogger(__FILE__, __LINE__, __FUNCTION__).debug + +//输出info级别日志 +#define KyInfo QMessageLogger(__FILE__, __LINE__, __FUNCTION__).info + +//输出warning级别日志 +#define KyWarning QMessageLogger(__FILE__, __LINE__, __FUNCTION__).warning + +//输出critical级别日志 +#define KyCritical QMessageLogger(__FILE__, __LINE__, __FUNCTION__).critical + +//输出fatal级别日志 +#define KyFatal QMessageLogger(__FILE__, __LINE__, __FUNCTION__).fatal + +// 初始化ukui-log4qt库,传入application名称 +int initUkuiLog4qt(QString strAppName); + +#endif // __UKUILOG4QT_H__ diff --git a/src/log4qt/ukui-log4qt.pro b/src/log4qt/ukui-log4qt.pro new file mode 100644 index 0000000..3616e9b --- /dev/null +++ b/src/log4qt/ukui-log4qt.pro @@ -0,0 +1,45 @@ +QT -= gui + +TEMPLATE = lib +DEFINES += LIBUKUILOG4QT_LIBRARY + +CONFIG += link_pkgconfig \ + c++11 + +PKGCONFIG += gsettings-qt + +# The following define makes your compiler emit warnings if you use +# any Qt feature that has been marked deprecated (the exact warnings +# depend on your compiler). Please consult the documentation of the +# deprecated API in order to know how to port your code away from it. +DEFINES += QT_DEPRECATED_WARNINGS + +# You can also make your code fail to compile if it uses deprecated APIs. +# In order to do so, uncomment the following line. +# You can also select to disable deprecated APIs only up to a certain version of Qt. +#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 + +#log4qt +include($$PWD/log4qt/log4qt.pri) + +SOURCES += \ + ukui-logconfigurator.cpp \ + ukui-logrolling.cpp \ + ukui-log4qt.cpp + +HEADERS += \ + ukui-logmacros.h \ + ukui-logconfigurator.h \ + ukui-logrolling.h \ + ukui-log4qt.h + +# Default rules for deployment. +unix { + target.path = /usr/lib + headers_main.path = /usr/include + headers_main.files += ukui-log4qt.h +} +!isEmpty(target.path): INSTALLS += target headers_main + +DISTFILES += \ + log4qt.conf diff --git a/src/log4qt/ukui-logconfigurator.cpp b/src/log4qt/ukui-logconfigurator.cpp new file mode 100644 index 0000000..624ab14 --- /dev/null +++ b/src/log4qt/ukui-logconfigurator.cpp @@ -0,0 +1,382 @@ +/* + * Copyright (C) 2021 Tianjin KYLIN Information Technology Co., Ltd. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see +#include + + +LOG4QT_GLOBAL_STATIC(QMutex, single_config) +UkuiLog4qtConfig *UkuiLog4qtConfig::mInstance = nullptr; + +UkuiLog4qtConfig::UkuiLog4qtConfig(QObject *parent) : + QObject(parent), + m_threadCheckFile(nullptr), + m_isInited(false), + m_gsLog4qtGlobal(nullptr), + m_gsLog4qtSpecial(nullptr) +{ + m_log4qtProperties.clear(); + m_uMaxFileCount = 0; + m_uMaxFileSize = 0; + m_timeCheckFile = 60; +} + +UkuiLog4qtConfig::~UkuiLog4qtConfig() +{ + if (m_gsLog4qtGlobal) { + delete m_gsLog4qtGlobal; + m_gsLog4qtGlobal = nullptr; + } + if (m_gsLog4qtSpecial) { + delete m_gsLog4qtSpecial; + m_gsLog4qtSpecial = nullptr; + } +} + +UkuiLog4qtConfig *UkuiLog4qtConfig::instance() +{ + if (!mInstance) + { + QMutexLocker locker(single_config()); + if (!mInstance) + { + mInstance = new UkuiLog4qtConfig; + } + } + return mInstance; +} + +int UkuiLog4qtConfig::init(QString strAppName) +{ + QMutexLocker locker(single_config()); + if (m_isInited) { + return true; + } + //全局设置 + m_log4qtProperties.clear(); + //是否重置所有配置,恢复全局设置默认值 + m_log4qtProperties.setProperty(UKUILOG4QT_RESET, "true"); + //设置日志sdk内部记录器级别 + m_log4qtProperties.setProperty(UKUILOG4QT_DEBUG, "INFO"); + //日志记录器仓库的阈值 + const QLatin1String key_threshold("log4j.threshold"); + m_log4qtProperties.setProperty(key_threshold, "NULL"); + //设置是否监听QDebug输出的字符串 + m_log4qtProperties.setProperty(UKUILOG4QT_HANDLEQT, "true"); + + //设置根Logger的输出log等级和输出目的地 + m_log4qtProperties.setProperty(UKUILOG4QT_ROOTLOGGER, "DEBUG,daily"); + + //设置终端打印记录器 + //记录器类别 --控制台输出 + const QLatin1String key_appender_console("log4j.appender.console"); + m_log4qtProperties.setProperty(key_appender_console, "org.apache.log4j.ConsoleAppender"); + //记录器输出目标 + const QLatin1String key_appender_console_target("log4j.appender.console.target"); + m_log4qtProperties.setProperty(key_appender_console_target, "STDOUT_TARGET"); + //记录器输出布局 + const QLatin1String key_appender_console_layout("log4j.appender.console.layout"); + m_log4qtProperties.setProperty(key_appender_console_layout, "org.apache.log4j.TTCCLayout"); + //记录器布局日期格式 + const QLatin1String key_appender_console_layout_dateformat("log4j.appender.console.layout.dateFormat"); + m_log4qtProperties.setProperty(key_appender_console_layout_dateformat, "yyy-MM-dd hh:mm:ss.zzz"); + //记录器布局包含上下文 + const QLatin1String key_appender_console_layout_contextprinting("log4j.appender.console.layout.contextPrinting"); + m_log4qtProperties.setProperty(key_appender_console_layout_contextprinting, "false"); + //记录器布局包含当前类目 + const QLatin1String key_appender_console_layout_categoryprefixing("log4j.appender.console.layout.categoryPrefixing"); + m_log4qtProperties.setProperty(key_appender_console_layout_categoryprefixing, "false"); + + + //设置定期文件滚动打印记录器 + //记录器类别 + const QLatin1String key_appender_daily("log4j.appender.daily"); + m_log4qtProperties.setProperty(key_appender_daily, "org.apache.log4j.DailyRollingFileAppender"); + //记录器输出文件路径 + const QLatin1String key_appender_daily_file("log4j.appender.daily.file"); + QStringList homePath = QStandardPaths::standardLocations(QStandardPaths::HomeLocation); + if (homePath.size() <= 0) { + return -1; + } + QString strLogFilePath = homePath[0]+UKUILOG4QT_ROOTPATH+strAppName+".log"; + m_log4qtProperties.setProperty(key_appender_daily_file, strLogFilePath); + //记录器追加文件内容 + const QLatin1String key_appender_daily_appendfile("log4j.appender.daily.appendFile"); + m_log4qtProperties.setProperty(key_appender_daily_appendfile, "true"); + //记录器是否直接写入文件 + const QLatin1String key_appender_daily_immediateflush("log4j.appender.daily.immediateFlush"); + m_log4qtProperties.setProperty(key_appender_daily_immediateflush, "true"); + //记录器文件名日期后缀 按天 + m_log4qtProperties.setProperty(UKUILOG4QT_DAILY_DATEPATTERN, ".yyyy-MM-dd"); + //记录器布局分隔符 + const QLatin1String key_appender_daily_layout("log4j.appender.daily.layout"); + m_log4qtProperties.setProperty(key_appender_daily_layout, "org.apache.log4j.PatternLayout"); + //记录器日志输出格式 + m_log4qtProperties.setProperty(UKUILOG4QT_DAILY_CONVERSIONPATTERN, "%d{yyyy-MM-dd HH:mm:ss,zzz}(%-4r)[%t]|%-5p| - %m%n"); + + // 从gsettings获取属性值 + initSettings(strAppName, m_log4qtProperties); + + // 根据配置属性初始化rootlogger + if (!Log4Qt::PropertyConfigurator::configure(m_log4qtProperties)) { + return -2; + } + // 注册程序销毁回调函数 + atexit(shutdown); + // 启动检查日志文件数量和大小线程 + m_threadCheckFile = new UkuiLog4qtRolling(strLogFilePath, m_uMaxFileCount, m_uMaxFileSize, m_timeCheckFile); + m_threadCheckFile->start(); + // 更新已初始化状态 + m_isInited = true; + return 0; +} + +void UkuiLog4qtConfig::shutdown() +{ + QMutexLocker locker(single_config()); + if (mInstance) { + if (mInstance->m_threadCheckFile) { + mInstance->m_threadCheckFile->stop(); + mInstance->m_threadCheckFile->wait(); + delete mInstance->m_threadCheckFile; + mInstance->m_threadCheckFile = nullptr; + } + delete mInstance; + mInstance = nullptr; + } +} + +void UkuiLog4qtConfig::initSettings(QString strAppName, Log4Qt::Properties &properties) +{ + //读取全局gsettings配置 + const QByteArray gid(UKUILOG4QT_SETTINGS); + if(QGSettings::isSchemaInstalled(gid)) + { + m_gsLog4qtGlobal = new QGSettings(gid); + connect(m_gsLog4qtGlobal,&QGSettings::changed,[=](QString key) + { + QMutexLocker locker(single_config()); + QVariant gValue; + bool bLogConfigChange = false; + bool bLogRollingChange = false; + if (UKUILOG4QT_SETTINGS_RESET == key) { + gValue = m_gsLog4qtGlobal->get(UKUILOG4QT_SETTINGS_RESET); + if (gValue.isValid()) { + m_log4qtProperties.setProperty(UKUILOG4QT_RESET, gValue.toString()); + bLogConfigChange = true; + } + } else if (UKUILOG4QT_SETTINGS_DEBUG == key) { + gValue = m_gsLog4qtGlobal->get(UKUILOG4QT_SETTINGS_DEBUG); + if (gValue.isValid()) { + m_log4qtProperties.setProperty(UKUILOG4QT_DEBUG, gValue.toString()); + bLogConfigChange = true; + } + } else if (UKUILOG4QT_SETTINGS_HANDLEQT == key) { + gValue = m_gsLog4qtGlobal->get(UKUILOG4QT_SETTINGS_HANDLEQT); + if (gValue.isValid()) { + m_log4qtProperties.setProperty(UKUILOG4QT_HANDLEQT, gValue.toString()); + bLogConfigChange = true; + } + } else if (UKUILOG4QT_SETTINGS_ROOTLOGGER == key) { + gValue = m_gsLog4qtGlobal->get(UKUILOG4QT_SETTINGS_ROOTLOGGER); + if (gValue.isValid()) { + m_log4qtProperties.setProperty(UKUILOG4QT_ROOTLOGGER, gValue.toString()); + bLogConfigChange = true; + } + } else if (UKUILOG4QT_SETTINGS_DAILY_DATEPATTERN == key) { + gValue = m_gsLog4qtGlobal->get(UKUILOG4QT_SETTINGS_DAILY_DATEPATTERN); + if (gValue.isValid()) { + m_log4qtProperties.setProperty(UKUILOG4QT_DAILY_DATEPATTERN, gValue.toString()); + bLogConfigChange = true; + } + } else if (UKUILOG4QT_SETTINGS_DAILY_CONVERSIONPATTERN == key) { + gValue = m_gsLog4qtGlobal->get(UKUILOG4QT_SETTINGS_DAILY_CONVERSIONPATTERN); + if (gValue.isValid()) { + m_log4qtProperties.setProperty(UKUILOG4QT_DAILY_CONVERSIONPATTERN, gValue.toString()); + bLogConfigChange = true; + } + } + if (bLogConfigChange) { + Log4Qt::PropertyConfigurator::configure(m_log4qtProperties); + } + if (UKUILOG4QT_SETTINGS_ROLLINGCHECK_DELAYTIME == key) { + gValue = m_gsLog4qtGlobal->get(UKUILOG4QT_SETTINGS_ROLLINGCHECK_DELAYTIME); + if (gValue.isValid()) { + m_timeCheckFile = gValue.toULongLong(); + bLogRollingChange = true; + } + } else if (UKUILOG4QT_SETTINGS_ROLLINGCHECK_MAXFILECOUNT == key) { + gValue = m_gsLog4qtGlobal->get(UKUILOG4QT_SETTINGS_ROLLINGCHECK_MAXFILECOUNT); + if (gValue.isValid()) { + m_uMaxFileCount = gValue.toUInt(); + bLogRollingChange = true; + } + } else if (UKUILOG4QT_SETTINGS_ROLLINGCHECK_MAXFILESIZE == key) { + gValue = m_gsLog4qtGlobal->get(UKUILOG4QT_SETTINGS_ROLLINGCHECK_MAXFILESIZE); + if (gValue.isValid()) { + m_uMaxFileSize = gValue.toULongLong(); + bLogRollingChange = true; + } + } + if (bLogRollingChange && m_threadCheckFile) { + m_threadCheckFile->setFileCheckLimit(m_uMaxFileCount, m_uMaxFileSize, m_timeCheckFile); + } + }); + } + if (m_gsLog4qtGlobal) { + QVariant gValue = m_gsLog4qtGlobal->get(UKUILOG4QT_SETTINGS_RESET); + if (gValue.isValid()) { + properties.setProperty(UKUILOG4QT_RESET, gValue.toString()); + } + gValue = m_gsLog4qtGlobal->get(UKUILOG4QT_SETTINGS_DEBUG); + if (gValue.isValid()) { + properties.setProperty(UKUILOG4QT_DEBUG, gValue.toString()); + } + gValue = m_gsLog4qtGlobal->get(UKUILOG4QT_SETTINGS_HANDLEQT); + if (gValue.isValid()) { + properties.setProperty(UKUILOG4QT_HANDLEQT, gValue.toString()); + } + gValue = m_gsLog4qtGlobal->get(UKUILOG4QT_SETTINGS_ROOTLOGGER); + if (gValue.isValid()) { + properties.setProperty(UKUILOG4QT_ROOTLOGGER, gValue.toString()); + } + gValue = m_gsLog4qtGlobal->get(UKUILOG4QT_SETTINGS_DAILY_DATEPATTERN); + if (gValue.isValid()) { + properties.setProperty(UKUILOG4QT_DAILY_DATEPATTERN, gValue.toString()); + } + gValue = m_gsLog4qtGlobal->get(UKUILOG4QT_SETTINGS_DAILY_CONVERSIONPATTERN); + if (gValue.isValid()) { + properties.setProperty(UKUILOG4QT_DAILY_CONVERSIONPATTERN, gValue.toString()); + } + gValue = m_gsLog4qtGlobal->get(UKUILOG4QT_SETTINGS_ROLLINGCHECK_DELAYTIME); + if (gValue.isValid()) { + m_timeCheckFile = gValue.toULongLong(); + } + gValue = m_gsLog4qtGlobal->get(UKUILOG4QT_SETTINGS_ROLLINGCHECK_MAXFILECOUNT); + if (gValue.isValid()) { + m_uMaxFileCount = gValue.toUInt(); + } + gValue = m_gsLog4qtGlobal->get(UKUILOG4QT_SETTINGS_ROLLINGCHECK_MAXFILESIZE); + if (gValue.isValid()) { + m_uMaxFileSize = gValue.toULongLong(); + } + } + //读取特例gsettings配置 + QString strSpecialSetting = QString("%1-%2").arg(UKUILOG4QT_SETTINGS).arg(strAppName); + const QByteArray sid = strSpecialSetting.toUtf8(); + if(QGSettings::isSchemaInstalled(sid)) + { + m_gsLog4qtSpecial = new QGSettings(sid); + connect(m_gsLog4qtSpecial,&QGSettings::changed,[=](QString key) + { + QMutexLocker locker(single_config()); + QVariant gValue; + bool bLogConfigChange = false; + bool bLogRollingChange = false; + if (UKUILOG4QT_SETTINGS_HANDLEQT == key) { + gValue = m_gsLog4qtSpecial->get(UKUILOG4QT_SETTINGS_HANDLEQT); + if (gValue.isValid()) { + m_log4qtProperties.setProperty(UKUILOG4QT_HANDLEQT, gValue.toString()); + bLogConfigChange = true; + } + }else if (UKUILOG4QT_SETTINGS_ROOTLOGGER == key) { + gValue = m_gsLog4qtSpecial->get(UKUILOG4QT_SETTINGS_ROOTLOGGER); + if (gValue.isValid()) { + m_log4qtProperties.setProperty(UKUILOG4QT_ROOTLOGGER, gValue.toString()); + bLogConfigChange = true; + } + } else if (UKUILOG4QT_SETTINGS_DAILY_DATEPATTERN == key) { + gValue = m_gsLog4qtSpecial->get(UKUILOG4QT_SETTINGS_DAILY_DATEPATTERN); + if (gValue.isValid()) { + m_log4qtProperties.setProperty(UKUILOG4QT_DAILY_DATEPATTERN, gValue.toString()); + bLogConfigChange = true; + } + } else if (UKUILOG4QT_SETTINGS_DAILY_CONVERSIONPATTERN == key) { + gValue = m_gsLog4qtSpecial->get(UKUILOG4QT_SETTINGS_DAILY_CONVERSIONPATTERN); + if (gValue.isValid()) { + m_log4qtProperties.setProperty(UKUILOG4QT_DAILY_CONVERSIONPATTERN, gValue.toString()); + bLogConfigChange = true; + } + } + if (bLogConfigChange) { + Log4Qt::PropertyConfigurator::configure(m_log4qtProperties); + } + if (UKUILOG4QT_SETTINGS_ROLLINGCHECK_DELAYTIME == key) { + gValue = m_gsLog4qtSpecial->get(UKUILOG4QT_SETTINGS_ROLLINGCHECK_DELAYTIME); + if (gValue.isValid()) { + m_timeCheckFile = gValue.toULongLong(); + bLogRollingChange = true; + } + } else if (UKUILOG4QT_SETTINGS_ROLLINGCHECK_MAXFILECOUNT == key) { + gValue = m_gsLog4qtSpecial->get(UKUILOG4QT_SETTINGS_ROLLINGCHECK_MAXFILECOUNT); + if (gValue.isValid()) { + m_uMaxFileCount = gValue.toUInt(); + bLogRollingChange = true; + } + } else if (UKUILOG4QT_SETTINGS_ROLLINGCHECK_MAXFILESIZE == key) { + gValue = m_gsLog4qtSpecial->get(UKUILOG4QT_SETTINGS_ROLLINGCHECK_MAXFILESIZE); + if (gValue.isValid()) { + m_uMaxFileSize = gValue.toULongLong(); + bLogRollingChange = true; + } + } + if (bLogRollingChange && m_threadCheckFile) { + m_threadCheckFile->setFileCheckLimit(m_uMaxFileCount, m_uMaxFileSize, m_timeCheckFile); + } + }); + } + if (m_gsLog4qtSpecial) { + QVariant gValue = m_gsLog4qtSpecial->get(UKUILOG4QT_SETTINGS_ROOTLOGGER); + if (gValue.isValid()) { + properties.setProperty(UKUILOG4QT_ROOTLOGGER, gValue.toString()); + } + gValue = m_gsLog4qtSpecial->get(UKUILOG4QT_SETTINGS_HANDLEQT); + if (gValue.isValid()) { + properties.setProperty(UKUILOG4QT_HANDLEQT, gValue.toString()); + } + gValue = m_gsLog4qtSpecial->get(UKUILOG4QT_SETTINGS_DAILY_DATEPATTERN); + if (gValue.isValid()) { + properties.setProperty(UKUILOG4QT_DAILY_DATEPATTERN, gValue.toString()); + } + gValue = m_gsLog4qtSpecial->get(UKUILOG4QT_SETTINGS_DAILY_CONVERSIONPATTERN); + if (gValue.isValid()) { + properties.setProperty(UKUILOG4QT_DAILY_CONVERSIONPATTERN, gValue.toString()); + } + gValue = m_gsLog4qtSpecial->get(UKUILOG4QT_SETTINGS_ROLLINGCHECK_DELAYTIME); + if (gValue.isValid()) { + m_timeCheckFile = gValue.toULongLong(); + } + gValue = m_gsLog4qtSpecial->get(UKUILOG4QT_SETTINGS_ROLLINGCHECK_MAXFILECOUNT); + if (gValue.isValid()) { + m_uMaxFileCount = gValue.toUInt(); + } + gValue = m_gsLog4qtSpecial->get(UKUILOG4QT_SETTINGS_ROLLINGCHECK_MAXFILESIZE); + if (gValue.isValid()) { + m_uMaxFileSize = gValue.toULongLong(); + } + } +} \ No newline at end of file diff --git a/src/log4qt/ukui-logconfigurator.h b/src/log4qt/ukui-logconfigurator.h new file mode 100644 index 0000000..031fa30 --- /dev/null +++ b/src/log4qt/ukui-logconfigurator.h @@ -0,0 +1,74 @@ +/* + * Copyright (C) 2021 Tianjin KYLIN Information Technology Co., Ltd. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see +#include +#include +#include "log4qt/helpers/properties.h" +#include "ukui-logrolling.h" + +// 日志sdk对外衔接类 +class LIBUKUILOG4QT_EXPORT UkuiLog4qtConfig : public QObject +{ + Q_OBJECT + +private: + virtual ~UkuiLog4qtConfig(); + UkuiLog4qtConfig(QObject *parent = nullptr); + +public: + // 返回日志配置器实例 + static UkuiLog4qtConfig *instance(); + // 初始化日志sdk属性 + int init(QString strAppName); + // 释放自身资源 + static void shutdown(); + +private: + // 初始化gsettings并监听 + void initSettings(QString strAppName, Log4Qt::Properties &properties); + +public: + // 检查日志文件线程对象 + UkuiLog4qtRolling *m_threadCheckFile; + +private: + // 自身实例 + static UkuiLog4qtConfig *mInstance; + // 是否已初始化 + bool m_isInited; + // 全局gsettings + QGSettings *m_gsLog4qtGlobal; + // 当前程序特例gsettings + QGSettings *m_gsLog4qtSpecial; + // 当前属性列表 + Log4Qt::Properties m_log4qtProperties; + // 最多允许文件数 + unsigned m_uMaxFileCount; + // 最大允许文件容量 + quint64 m_uMaxFileSize; + // 文件检查时间间隔 s + quint64 m_timeCheckFile; +}; + +#endif // __UKUI_LOGCONFIGURATOR_H__ \ No newline at end of file diff --git a/src/log4qt/ukui-logmacros.h b/src/log4qt/ukui-logmacros.h new file mode 100644 index 0000000..65a4a76 --- /dev/null +++ b/src/log4qt/ukui-logmacros.h @@ -0,0 +1,53 @@ +/* + * Copyright (C) 2021 Tianjin KYLIN Information Technology Co., Ltd. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see + +#if defined(LIBUKUILOG4QT_LIBRARY) +# define LIBUKUILOG4QT_EXPORT Q_DECL_EXPORT +#else +# define LIBUKUILOG4QT_EXPORT Q_DECL_IMPORT +#endif + +// 日志文件相对home目录路径 +#define UKUILOG4QT_ROOTPATH "/.config/ukui/" + +// gsettings相关相关属性 +#define UKUILOG4QT_SETTINGS "org.ukui.ukui-log4qt" +#define UKUILOG4QT_SETTINGS_RESET "log4jReset" +#define UKUILOG4QT_SETTINGS_DEBUG "log4jDebug" +#define UKUILOG4QT_SETTINGS_HANDLEQT "log4jHandleqtmessages" +#define UKUILOG4QT_SETTINGS_ROOTLOGGER "log4jRootlogger" +#define UKUILOG4QT_SETTINGS_DAILY_DATEPATTERN "log4jAppenderDailyDatepattern" +#define UKUILOG4QT_SETTINGS_DAILY_CONVERSIONPATTERN "log4jAppenderDailyLayoutConversionpattern" +#define UKUILOG4QT_SETTINGS_ROLLINGCHECK_DELAYTIME "delaytime" +#define UKUILOG4QT_SETTINGS_ROLLINGCHECK_MAXFILECOUNT "maxfilecount" +#define UKUILOG4QT_SETTINGS_ROLLINGCHECK_MAXFILESIZE "maxfilesize" + +// log4qt相关属性 +#define UKUILOG4QT_RESET "log4j.reset" //是否重置所有配置,恢复全局设置默认值 +#define UKUILOG4QT_DEBUG "log4j.Debug" //设置日志sdk内部记录器级别 +#define UKUILOG4QT_HANDLEQT "log4j.handleQtMessages" //设置是否监听QDebug输出的字符串 +#define UKUILOG4QT_ROOTLOGGER "log4j.rootLogger" //设置根Logger的输出log等级和输出目的地 +#define UKUILOG4QT_DAILY_DATEPATTERN "log4j.appender.daily.datePattern" //记录器文件名日期后缀 按天 +#define UKUILOG4QT_DAILY_CONVERSIONPATTERN "log4j.appender.daily.layout.conversionPattern" //记录器日志输出格式 + +#endif // __UKUI_LOGMACROS__ diff --git a/src/log4qt/ukui-logrolling.cpp b/src/log4qt/ukui-logrolling.cpp new file mode 100644 index 0000000..b31c6b3 --- /dev/null +++ b/src/log4qt/ukui-logrolling.cpp @@ -0,0 +1,175 @@ +/* + * Copyright (C) 2021 Tianjin KYLIN Information Technology Co., Ltd. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see +#include +#include +#include + +UkuiLog4qtRolling::UkuiLog4qtRolling(QString strBaseFilePath, unsigned uMaxFileCount, quint64 uMaxFileSize, + quint64 delayCheckFileTime, QObject *parent) : + QThread(parent), + m_isExit(false), + m_delayCheckFileTime(delayCheckFileTime), + m_strBaseFilePath(strBaseFilePath), + m_uMaxFileCount(uMaxFileCount), + m_uMaxFileSize(uMaxFileSize*1024*1024) // 单位 M +{ +} + +UkuiLog4qtRolling::~UkuiLog4qtRolling() +{ + +} + +// 线程过程 +void UkuiLog4qtRolling::run() +{ + // 时间间隔参数异常 + if (m_delayCheckFileTime == 0) { + return ; + } + + // 定时检查日志文件和大小 + while (!m_isExit && m_delayCheckFileTime != 0) { + m_lockReadWrite.lockForRead(); + if (m_uMaxFileCount > 0) { + checkLogFilesCount(); + } + if (m_uMaxFileSize > 0) { + checkLogFilesSize(); + } + quint64 willDelayCheckFileTime = m_delayCheckFileTime*1000; + m_lockReadWrite.unlock(); + // 细化sleep片段 + while (!m_isExit && willDelayCheckFileTime >= 50 && !m_isConfigChange) { + QThread::msleep(50); + willDelayCheckFileTime -= 50; + } + m_lockReadWrite.lockForWrite(); + m_isConfigChange = false; + m_lockReadWrite.unlock(); + if (m_isExit) { + break; + } + } +} + +// 设置文件检查限制条件 +void UkuiLog4qtRolling::setFileCheckLimit(unsigned uMaxFileCount, quint64 uMaxFileSize, quint64 delayCheckFileTime) +{ + m_lockReadWrite.lockForWrite(); + m_uMaxFileCount = uMaxFileCount; + m_uMaxFileSize = uMaxFileSize*1024*1024; // 单位 M + m_delayCheckFileTime = delayCheckFileTime; + m_isConfigChange = true; + m_lockReadWrite.unlock(); +} + +// 停止线程 +void UkuiLog4qtRolling::stop() +{ + m_isExit = true; +} + +// 检查文件数量 +void UkuiLog4qtRolling::checkLogFilesCount() +{ + if (m_strBaseFilePath.isEmpty()) { + return; + } + + QFileInfo fileInfo(m_strBaseFilePath); + if (!fileInfo.exists()) { + return; + } + QDir dir(fileInfo.path()); + if (!dir.exists()) { + return ; + } + dir.setFilter(QDir::Files | QDir::NoSymLinks); + QStringList filters; + filters<= 0; i--) { + if (willRmFileCount <= 0) { + break; + } + QString filePath = fileInfoList[i].absoluteFilePath(); + KyDebug()<<"Will Remove File:"<= 0; i--) { + if (willRmFileSize <= 0) { + break; + } + QString filePath = fileInfoList[i].absoluteFilePath(); + KyDebug()<<"Will Remove File:"< +#include + +class UkuiLog4qtRolling : public QThread +{ +public: + UkuiLog4qtRolling(QString strBaseFilePath, unsigned uMaxFileCount = 0, quint64 uMaxFileSize = 0, + quint64 delayCheckFileTime = 0, QObject *parent = nullptr); + virtual ~UkuiLog4qtRolling(); + + // 停止线程 + void stop(); + // 设置文件检查限制条件 + void setFileCheckLimit(unsigned uMaxFileCount = 0, quint64 uMaxFileSize = 0, quint64 delayCheckFileTime = 0); + // 检查文件数量 + void checkLogFilesCount(); + // 检查文件大小 + void checkLogFilesSize(); + +protected: + void run(); + +private: + // 是否将线程退出 + bool m_isExit = true; + // 间隔检查文件时间 单位(s) + quint64 m_delayCheckFileTime = 0; + // 当前基础文件路径 + QString m_strBaseFilePath; + // 最大文件数限制 + unsigned m_uMaxFileCount = 0; + // 最大文件大小限制 + quint64 m_uMaxFileSize = 0; + // 数据保护锁 + QReadWriteLock m_lockReadWrite; + // 配置是否修改 + bool m_isConfigChange = false; +}; + +#endif // __UKUILOG4QT_ROLLING_H__ \ No newline at end of file From 56ce55b7230b15b81b83e7372202e87ed4cf3c91 Mon Sep 17 00:00:00 2001 From: winnerym100 Date: Sat, 10 Apr 2021 14:32:03 +0800 Subject: [PATCH 02/35] =?UTF-8?q?feature=EF=BC=9A=E5=A2=9E=E5=8A=A0QT?= =?UTF-8?q?=E6=97=A5=E5=BF=97=E5=BA=93=E9=BB=98=E8=AE=A4=E9=85=8D=E7=BD=AE?= =?UTF-8?q?=E6=96=87=E4=BB=B6=E6=89=93=E5=8C=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- debian/libukui-log4qt-dev.install | 1 + debian/libukui-log4qt-dev.postinst | 5 +++++ src/log4qt/ukui-log4qt.pro | 13 ++++++++++--- 3 files changed, 16 insertions(+), 3 deletions(-) create mode 100644 debian/libukui-log4qt-dev.postinst diff --git a/debian/libukui-log4qt-dev.install b/debian/libukui-log4qt-dev.install index 436cbbd..d7e9981 100644 --- a/debian/libukui-log4qt-dev.install +++ b/debian/libukui-log4qt-dev.install @@ -1,2 +1,3 @@ usr/include/ukui-log4qt.h usr/lib/libukui-log4qt.so +usr/share/glib-2.0/schemas/org.ukui.log4qt.gschema.xml diff --git a/debian/libukui-log4qt-dev.postinst b/debian/libukui-log4qt-dev.postinst new file mode 100644 index 0000000..cca3fa9 --- /dev/null +++ b/debian/libukui-log4qt-dev.postinst @@ -0,0 +1,5 @@ +#!/bin/sh + +glib-compile-schemas /usr/share/glib-2.0/schemas/ + +#DEBHELPER# diff --git a/src/log4qt/ukui-log4qt.pro b/src/log4qt/ukui-log4qt.pro index 3616e9b..5025e0c 100644 --- a/src/log4qt/ukui-log4qt.pro +++ b/src/log4qt/ukui-log4qt.pro @@ -36,10 +36,17 @@ HEADERS += \ # Default rules for deployment. unix { target.path = /usr/lib - headers_main.path = /usr/include - headers_main.files += ukui-log4qt.h } -!isEmpty(target.path): INSTALLS += target headers_main +!isEmpty(target.path): INSTALLS += target + +schemes.files += org.ukui.log4qt.gschema.xml +schemes.path = /usr/share/glib-2.0/schemas/ + +headers_main.path = /usr/include +headers_main.files += ukui-log4qt.h + +INSTALLS += schemes \ + headers_main DISTFILES += \ log4qt.conf From 1cc915f31e550ca93cd93bc42b912407fdbe07eb Mon Sep 17 00:00:00 2001 From: winnerym100 Date: Fri, 16 Apr 2021 16:04:10 +0800 Subject: [PATCH 03/35] =?UTF-8?q?fix=EF=BC=9A=E4=BF=AE=E5=A4=8D=E7=A8=8B?= =?UTF-8?q?=E5=BA=8F=E9=87=8D=E5=90=AF=E6=97=B6=E6=9C=AA=E6=8C=89=E6=97=A5?= =?UTF-8?q?=E6=9C=9F=E5=88=86=E5=89=B2=E6=96=87=E4=BB=B6=E9=97=AE=E9=A2=98?= =?UTF-8?q?=EF=BC=9B=E4=BC=98=E5=8C=96=E5=8A=9F=E8=83=BD=EF=BC=9A=E4=BC=98?= =?UTF-8?q?=E5=8C=96=E7=BC=96=E5=8C=85=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- debian/changelog | 12 +++ debian/copyright | 18 +++- debian/libukui-log4qt-dev.install | 1 - debian/libukui-log4qt0.install | 1 + ...-dev.postinst => libukui-log4qt0.postinst} | 0 debian/rules | 22 ++++- src/log4qt/debian/copyright | 17 +++- .../log4qt/dailyrollingfileappender.cpp | 97 ++++++++++++++++++- src/log4qt/log4qt/dailyrollingfileappender.h | 1 + 9 files changed, 156 insertions(+), 13 deletions(-) rename debian/{libukui-log4qt-dev.postinst => libukui-log4qt0.postinst} (100%) diff --git a/debian/changelog b/debian/changelog index b8b6e0e..d6d6069 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,15 @@ +ukui-interface (1.0.1-2) v101; urgency=medium + + * 修复bug:修复隔天重新打开程序时日志文件未按日期分割 + + -- Yang Min Fri, 16 Apr 2021 15:38:18 +0800 + +ukui-interface (1.0.1-1) v101; urgency=medium + + * 完善功能:将qt日志库默认配置文件打包进deb + + -- Yang Min Sat, 10 Apr 2021 14:32:55 +0800 + ukui-interface (1.0.1) v101; urgency=medium * 增加功能:增加qt日志打印包 diff --git a/debian/copyright b/debian/copyright index 91f63a8..f422f50 100644 --- a/debian/copyright +++ b/debian/copyright @@ -9,6 +9,20 @@ Files: src/log4qt/doc/* src/log4qt/tests/* Copyright: 2007 - 2009 Martin Heinrich License: Apache-2.0 + 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. + . + On Debian systems, the complete text of the Apache License Version 2.0 + can be found in `/usr/share/common-licenses/Apache-2.0'. Files: src/log4qt/ukui-log4qt.h src/log4qt/ukui-log4qt.cpp @@ -28,10 +42,6 @@ Files: debian/* Copyright: 2019 liuhao License: GPL-3.0+ -License: Apache-2.0 - On Debian systems, the complete text of the Apache-2.0 can be found - in `/usr/share/common-licenses/Apache-2.0'. - License: GPL-3.0+ This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/debian/libukui-log4qt-dev.install b/debian/libukui-log4qt-dev.install index d7e9981..436cbbd 100644 --- a/debian/libukui-log4qt-dev.install +++ b/debian/libukui-log4qt-dev.install @@ -1,3 +1,2 @@ usr/include/ukui-log4qt.h usr/lib/libukui-log4qt.so -usr/share/glib-2.0/schemas/org.ukui.log4qt.gschema.xml diff --git a/debian/libukui-log4qt0.install b/debian/libukui-log4qt0.install index 9baf7fe..5d3e9a7 100644 --- a/debian/libukui-log4qt0.install +++ b/debian/libukui-log4qt0.install @@ -1 +1,2 @@ usr/lib/libukui-log4qt.so.* +usr/share/glib-2.0/schemas/org.ukui.log4qt.gschema.xml diff --git a/debian/libukui-log4qt-dev.postinst b/debian/libukui-log4qt0.postinst similarity index 100% rename from debian/libukui-log4qt-dev.postinst rename to debian/libukui-log4qt0.postinst diff --git a/debian/rules b/debian/rules index 2c7f82c..e68d54d 100755 --- a/debian/rules +++ b/debian/rules @@ -7,13 +7,18 @@ export DEB_BUILD_MAINT_OPTIONS = hardening=+all #export DEB_CFLAGS_MAINT_APPEND = -Wall -pedantic #export DEB_LDFLAGS_MAINT_APPEND = -Wl,--as-needed QT_INSTALL_DIR:=$(shell pwd)/debian/tmp/ +LOG4QT_BUILD_DIR:=$(shell pwd)/src/log4qt/build %: dh $@ +override_dh_auto_clean: + dh_auto_clean + rm -fr $(LOG4QT_BUILD_DIR) + override_dh_install: mkdir -p $(QT_INSTALL_DIR) && \ - make install INSTALL_ROOT=$(QT_INSTALL_DIR) -C src/log4qt/build + make install INSTALL_ROOT=$(QT_INSTALL_DIR) -C $(LOG4QT_BUILD_DIR) dh_install override_dh_auto_configure: @@ -23,6 +28,15 @@ override_dh_auto_configure: override_dh_auto_build: dh_auto_build - mkdir -p src/log4qt/build - cd src/log4qt/build && qmake ../ - make -C src/log4qt/build + mkdir -p $(LOG4QT_BUILD_DIR) + cd $(LOG4QT_BUILD_DIR) && qmake -makefile "QMAKE_CFLAGS_RELEASE=-g -O2 -fdebug-prefix-map=$(LOG4QT_BUILD_DIR)=. \ + -fstack-protector-strong -Wformat -Werror=format-security -Wdate-time -D_FORTIFY_SOURCE=2" \ + "QMAKE_CFLAGS_DEBUG=-g -O2 -fdebug-prefix-map=$(LOG4QT_BUILD_DIR)=. -fstack-protector-strong \ + -Wformat -Werror=format-security -Wdate-time -D_FORTIFY_SOURCE=2" \ + "QMAKE_CXXFLAGS_RELEASE=-g -O2 -fdebug-prefix-map=$(LOG4QT_BUILD_DIR)=. -fstack-protector-strong \ + -Wformat -Werror=format-security -Wdate-time -D_FORTIFY_SOURCE=2" \ + "QMAKE_CXXFLAGS_DEBUG=-g -O2 -fdebug-prefix-map=$(LOG4QT_BUILD_DIR)=. \ + -fstack-protector-strong -Wformat -Werror=format-security -Wdate-time -D_FORTIFY_SOURCE=2" \ + "QMAKE_LFLAGS_RELEASE=-Wl,-Bsymbolic-functions -Wl,-z,relro -Wl,-z,now" \ + "QMAKE_LFLAGS_DEBUG=-Wl,-Bsymbolic-functions -Wl,-z,relro -Wl,-z,now" QMAKE_STRIP=: PREFIX=/usr .. + make -C $(LOG4QT_BUILD_DIR) diff --git a/src/log4qt/debian/copyright b/src/log4qt/debian/copyright index 4ccd190..f7f0d3c 100644 --- a/src/log4qt/debian/copyright +++ b/src/log4qt/debian/copyright @@ -9,6 +9,20 @@ Files: * tests/* Copyright: 2007 - 2009 Martin Heinrich License: Apache-2.0 + 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. + . + On Debian systems, the complete text of the Apache License Version 2.0 + can be found in `/usr/share/common-licenses/Apache-2.0'. Files: debian/* Copyright: 2020 Tianjin KYLIN Information Technology Co., Ltd. @@ -29,6 +43,3 @@ License: GPL-3.0+ On Debian systems, the complete text of the GNU General Public License Version 3 can be found in `/usr/share/common-licenses/GPL-3'. -License: Apache-2.0 - On Debian systems, the complete text of the Apache-2.0 can be found - in `/usr/share/common-licenses/Apache-2.0'. diff --git a/src/log4qt/log4qt/dailyrollingfileappender.cpp b/src/log4qt/log4qt/dailyrollingfileappender.cpp index 0590f16..fdedb33 100644 --- a/src/log4qt/log4qt/dailyrollingfileappender.cpp +++ b/src/log4qt/log4qt/dailyrollingfileappender.cpp @@ -33,6 +33,7 @@ #include #include +#include #include #include #include "log4qt/helpers/datetime.h" @@ -123,7 +124,16 @@ namespace Log4Qt computeFrequency(); if (!mActiveDatePattern.isEmpty()) { - computeRollOverTime(); + #if 1 + QFileInfo fileInfo(file()); + if (!fileInfo.exists()) { + computeRollOverTime(); + } else { + computeRollOverTime(fileInfo.birthTime()); + } + #else + computeRollOverTime(); + #endif FileAppender::activateOptions(); } } @@ -225,6 +235,91 @@ namespace Log4Qt frequencyToString()); } + void DailyRollingFileAppender::computeRollOverTime(QDateTime startTime) + { + // Q_ASSERT_X(, "DailyRollingFileAppender::computeRollOverTime()", "Lock must be held by caller") + Q_ASSERT_X(!mActiveDatePattern.isEmpty(), "DailyRollingFileAppender::computeRollOverTime()", "No active date pattern"); + + QDateTime now = startTime; + QDate now_date = now.date(); + QTime now_time = now.time(); + QDateTime start; + + switch (mFrequency) + { + case MINUTELY_ROLLOVER: + { + start = QDateTime(now_date, + QTime(now_time.hour(), + now_time.minute(), + 0, 0)); + mRollOverTime = start.addSecs(60); + } + break; + case HOURLY_ROLLOVER: + { + start = QDateTime(now_date, + QTime(now_time.hour(), + 0, 0, 0)); + mRollOverTime = start.addSecs(60*60); + } + break; + case HALFDAILY_ROLLOVER: + { + int hour = now_time.hour(); + if (hour >= 12) + hour = 12; + else + hour = 0; + start = QDateTime(now_date, + QTime(hour, 0, 0, 0)); + mRollOverTime = start.addSecs(60*60*12); + } + break; + case DAILY_ROLLOVER: + { + start = QDateTime(now_date, + QTime(0, 0, 0, 0)); + mRollOverTime = start.addDays(1); + } + break; + case WEEKLY_ROLLOVER: + { + // QT numbers the week days 1..7. The week starts on Monday. + // Change it to being numbered 0..6, starting with Sunday. + int day = now_date.dayOfWeek(); + if (day == Qt::Sunday) + day = 0; + start = QDateTime(now_date, + QTime(0, 0, 0, 0)).addDays(-1 * day); + mRollOverTime = start.addDays(7); + } + break; + case MONTHLY_ROLLOVER: + { + start = QDateTime(QDate(now_date.year(), + now_date.month(), + 1), + QTime(0, 0, 0, 0)); + mRollOverTime = start.addMonths(1); + } + break; + default: + Q_ASSERT_X(false, "DailyRollingFileAppender::computeInterval()", "Invalid datePattern constant"); + mRollOverTime = QDateTime::fromTime_t(0); + } + + mRollOverSuffix = static_cast(start).toString(mActiveDatePattern); + Q_ASSERT_X(static_cast(now).toString(mActiveDatePattern) == mRollOverSuffix, + "DailyRollingFileAppender::computeRollOverTime()", "File name changes within interval"); + Q_ASSERT_X(mRollOverSuffix != static_cast(mRollOverTime).toString(mActiveDatePattern), + "DailyRollingFileAppender::computeRollOverTime()", "File name does not change with rollover"); + + logger()->trace("Computing roll over time from %1: The interval start time is %2. The roll over time is %3", + now, + start, + mRollOverTime); + } void DailyRollingFileAppender::computeRollOverTime() { diff --git a/src/log4qt/log4qt/dailyrollingfileappender.h b/src/log4qt/log4qt/dailyrollingfileappender.h index f293b40..ee72eb9 100644 --- a/src/log4qt/log4qt/dailyrollingfileappender.h +++ b/src/log4qt/log4qt/dailyrollingfileappender.h @@ -158,6 +158,7 @@ namespace Log4Qt private: void computeFrequency(); void computeRollOverTime(); + void computeRollOverTime(QDateTime startTime); QString frequencyToString() const; void rollOver(); From 7e933cdc2731131c707458ec7fc63e1bf38ebe25 Mon Sep 17 00:00:00 2001 From: winnerym100 Date: Sat, 17 Apr 2021 16:31:56 +0800 Subject: [PATCH 04/35] =?UTF-8?q?=E5=88=A0=E9=99=A4=E5=A4=87=E4=BB=BD?= =?UTF-8?q?=E7=9A=84=E5=8E=9F=E5=A7=8B=E6=97=A5=E5=BF=97=E5=BA=93=E4=BB=A3?= =?UTF-8?q?=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/log4qt/src/log4qt/appender.h | 135 -- src/log4qt/src/log4qt/appenderskeleton.cpp | 261 --- src/log4qt/src/log4qt/appenderskeleton.h | 225 --- src/log4qt/src/log4qt/basicconfigurator.cpp | 107 -- src/log4qt/src/log4qt/basicconfigurator.h | 84 - src/log4qt/src/log4qt/consoleappender.cpp | 198 -- src/log4qt/src/log4qt/consoleappender.h | 160 -- .../src/log4qt/dailyrollingfileappender.cpp | 352 ---- .../src/log4qt/dailyrollingfileappender.h | 196 -- src/log4qt/src/log4qt/fileappender.cpp | 307 --- src/log4qt/src/log4qt/fileappender.h | 233 --- src/log4qt/src/log4qt/helpers/classlogger.cpp | 100 - src/log4qt/src/log4qt/helpers/classlogger.h | 115 -- .../src/log4qt/helpers/configuratorhelper.cpp | 136 -- .../src/log4qt/helpers/configuratorhelper.h | 210 --- src/log4qt/src/log4qt/helpers/datetime.cpp | 326 ---- src/log4qt/src/log4qt/helpers/datetime.h | 212 --- src/log4qt/src/log4qt/helpers/factory.cpp | 459 ----- src/log4qt/src/log4qt/helpers/factory.h | 492 ----- .../log4qt/helpers/initialisationhelper.cpp | 185 -- .../src/log4qt/helpers/initialisationhelper.h | 435 ----- src/log4qt/src/log4qt/helpers/logerror.cpp | 354 ---- src/log4qt/src/log4qt/helpers/logerror.h | 550 ------ src/log4qt/src/log4qt/helpers/logobject.cpp | 74 - src/log4qt/src/log4qt/helpers/logobject.h | 217 --- .../src/log4qt/helpers/logobjectptr.cpp | 65 - src/log4qt/src/log4qt/helpers/logobjectptr.h | 187 -- .../src/log4qt/helpers/optionconverter.cpp | 315 ---- .../src/log4qt/helpers/optionconverter.h | 150 -- .../src/log4qt/helpers/patternformatter.cpp | 893 --------- .../src/log4qt/helpers/patternformatter.h | 195 -- src/log4qt/src/log4qt/helpers/properties.cpp | 364 ---- src/log4qt/src/log4qt/helpers/properties.h | 161 -- src/log4qt/src/log4qt/hierarchy.cpp | 212 --- src/log4qt/src/log4qt/hierarchy.h | 141 -- src/log4qt/src/log4qt/layout.cpp | 91 - src/log4qt/src/log4qt/layout.h | 156 -- src/log4qt/src/log4qt/level.cpp | 204 -- src/log4qt/src/log4qt/level.h | 193 -- src/log4qt/src/log4qt/log4qt.cpp | 58 - src/log4qt/src/log4qt/log4qt.h | 614 ------ src/log4qt/src/log4qt/log4qt.pri | 111 -- src/log4qt/src/log4qt/logger.cpp | 349 ---- src/log4qt/src/log4qt/logger.h | 1665 ----------------- src/log4qt/src/log4qt/loggerrepository.cpp | 75 - src/log4qt/src/log4qt/loggerrepository.h | 128 -- src/log4qt/src/log4qt/loggingevent.cpp | 272 --- src/log4qt/src/log4qt/loggingevent.h | 221 --- src/log4qt/src/log4qt/logmanager.cpp | 504 ----- src/log4qt/src/log4qt/logmanager.h | 340 ---- src/log4qt/src/log4qt/mdc.cpp | 116 -- src/log4qt/src/log4qt/mdc.h | 122 -- src/log4qt/src/log4qt/ndc.cpp | 154 -- src/log4qt/src/log4qt/ndc.h | 121 -- src/log4qt/src/log4qt/patternlayout.cpp | 147 -- src/log4qt/src/log4qt/patternlayout.h | 159 -- .../src/log4qt/propertyconfigurator.cpp | 588 ------ src/log4qt/src/log4qt/propertyconfigurator.h | 194 -- src/log4qt/src/log4qt/rollingfileappender.cpp | 191 -- src/log4qt/src/log4qt/rollingfileappender.h | 164 -- src/log4qt/src/log4qt/simplelayout.cpp | 84 - src/log4qt/src/log4qt/simplelayout.h | 102 - src/log4qt/src/log4qt/spi/filter.cpp | 70 - src/log4qt/src/log4qt/spi/filter.h | 124 -- src/log4qt/src/log4qt/ttcclayout.cpp | 182 -- src/log4qt/src/log4qt/ttcclayout.h | 235 --- src/log4qt/src/log4qt/varia/debugappender.cpp | 127 -- src/log4qt/src/log4qt/varia/debugappender.h | 133 -- src/log4qt/src/log4qt/varia/denyallfilter.cpp | 77 - src/log4qt/src/log4qt/varia/denyallfilter.h | 105 -- .../src/log4qt/varia/levelmatchfilter.cpp | 100 - .../src/log4qt/varia/levelmatchfilter.h | 137 -- .../src/log4qt/varia/levelrangefilter.cpp | 104 - .../src/log4qt/varia/levelrangefilter.h | 153 -- src/log4qt/src/log4qt/varia/listappender.cpp | 153 -- src/log4qt/src/log4qt/varia/listappender.h | 174 -- src/log4qt/src/log4qt/varia/nullappender.cpp | 104 - src/log4qt/src/log4qt/varia/nullappender.h | 102 - .../src/log4qt/varia/stringmatchfilter.cpp | 101 - .../src/log4qt/varia/stringmatchfilter.h | 133 -- src/log4qt/src/log4qt/writerappender.cpp | 288 --- src/log4qt/src/log4qt/writerappender.h | 200 -- 82 files changed, 18731 deletions(-) delete mode 100644 src/log4qt/src/log4qt/appender.h delete mode 100644 src/log4qt/src/log4qt/appenderskeleton.cpp delete mode 100644 src/log4qt/src/log4qt/appenderskeleton.h delete mode 100644 src/log4qt/src/log4qt/basicconfigurator.cpp delete mode 100644 src/log4qt/src/log4qt/basicconfigurator.h delete mode 100644 src/log4qt/src/log4qt/consoleappender.cpp delete mode 100644 src/log4qt/src/log4qt/consoleappender.h delete mode 100644 src/log4qt/src/log4qt/dailyrollingfileappender.cpp delete mode 100644 src/log4qt/src/log4qt/dailyrollingfileappender.h delete mode 100644 src/log4qt/src/log4qt/fileappender.cpp delete mode 100644 src/log4qt/src/log4qt/fileappender.h delete mode 100644 src/log4qt/src/log4qt/helpers/classlogger.cpp delete mode 100644 src/log4qt/src/log4qt/helpers/classlogger.h delete mode 100644 src/log4qt/src/log4qt/helpers/configuratorhelper.cpp delete mode 100644 src/log4qt/src/log4qt/helpers/configuratorhelper.h delete mode 100644 src/log4qt/src/log4qt/helpers/datetime.cpp delete mode 100644 src/log4qt/src/log4qt/helpers/datetime.h delete mode 100644 src/log4qt/src/log4qt/helpers/factory.cpp delete mode 100644 src/log4qt/src/log4qt/helpers/factory.h delete mode 100644 src/log4qt/src/log4qt/helpers/initialisationhelper.cpp delete mode 100644 src/log4qt/src/log4qt/helpers/initialisationhelper.h delete mode 100644 src/log4qt/src/log4qt/helpers/logerror.cpp delete mode 100644 src/log4qt/src/log4qt/helpers/logerror.h delete mode 100644 src/log4qt/src/log4qt/helpers/logobject.cpp delete mode 100644 src/log4qt/src/log4qt/helpers/logobject.h delete mode 100644 src/log4qt/src/log4qt/helpers/logobjectptr.cpp delete mode 100644 src/log4qt/src/log4qt/helpers/logobjectptr.h delete mode 100644 src/log4qt/src/log4qt/helpers/optionconverter.cpp delete mode 100644 src/log4qt/src/log4qt/helpers/optionconverter.h delete mode 100644 src/log4qt/src/log4qt/helpers/patternformatter.cpp delete mode 100644 src/log4qt/src/log4qt/helpers/patternformatter.h delete mode 100644 src/log4qt/src/log4qt/helpers/properties.cpp delete mode 100644 src/log4qt/src/log4qt/helpers/properties.h delete mode 100644 src/log4qt/src/log4qt/hierarchy.cpp delete mode 100644 src/log4qt/src/log4qt/hierarchy.h delete mode 100644 src/log4qt/src/log4qt/layout.cpp delete mode 100644 src/log4qt/src/log4qt/layout.h delete mode 100644 src/log4qt/src/log4qt/level.cpp delete mode 100644 src/log4qt/src/log4qt/level.h delete mode 100644 src/log4qt/src/log4qt/log4qt.cpp delete mode 100644 src/log4qt/src/log4qt/log4qt.h delete mode 100644 src/log4qt/src/log4qt/log4qt.pri delete mode 100644 src/log4qt/src/log4qt/logger.cpp delete mode 100644 src/log4qt/src/log4qt/logger.h delete mode 100644 src/log4qt/src/log4qt/loggerrepository.cpp delete mode 100644 src/log4qt/src/log4qt/loggerrepository.h delete mode 100644 src/log4qt/src/log4qt/loggingevent.cpp delete mode 100644 src/log4qt/src/log4qt/loggingevent.h delete mode 100644 src/log4qt/src/log4qt/logmanager.cpp delete mode 100644 src/log4qt/src/log4qt/logmanager.h delete mode 100644 src/log4qt/src/log4qt/mdc.cpp delete mode 100644 src/log4qt/src/log4qt/mdc.h delete mode 100644 src/log4qt/src/log4qt/ndc.cpp delete mode 100644 src/log4qt/src/log4qt/ndc.h delete mode 100644 src/log4qt/src/log4qt/patternlayout.cpp delete mode 100644 src/log4qt/src/log4qt/patternlayout.h delete mode 100644 src/log4qt/src/log4qt/propertyconfigurator.cpp delete mode 100644 src/log4qt/src/log4qt/propertyconfigurator.h delete mode 100644 src/log4qt/src/log4qt/rollingfileappender.cpp delete mode 100644 src/log4qt/src/log4qt/rollingfileappender.h delete mode 100644 src/log4qt/src/log4qt/simplelayout.cpp delete mode 100644 src/log4qt/src/log4qt/simplelayout.h delete mode 100644 src/log4qt/src/log4qt/spi/filter.cpp delete mode 100644 src/log4qt/src/log4qt/spi/filter.h delete mode 100644 src/log4qt/src/log4qt/ttcclayout.cpp delete mode 100644 src/log4qt/src/log4qt/ttcclayout.h delete mode 100644 src/log4qt/src/log4qt/varia/debugappender.cpp delete mode 100644 src/log4qt/src/log4qt/varia/debugappender.h delete mode 100644 src/log4qt/src/log4qt/varia/denyallfilter.cpp delete mode 100644 src/log4qt/src/log4qt/varia/denyallfilter.h delete mode 100644 src/log4qt/src/log4qt/varia/levelmatchfilter.cpp delete mode 100644 src/log4qt/src/log4qt/varia/levelmatchfilter.h delete mode 100644 src/log4qt/src/log4qt/varia/levelrangefilter.cpp delete mode 100644 src/log4qt/src/log4qt/varia/levelrangefilter.h delete mode 100644 src/log4qt/src/log4qt/varia/listappender.cpp delete mode 100644 src/log4qt/src/log4qt/varia/listappender.h delete mode 100644 src/log4qt/src/log4qt/varia/nullappender.cpp delete mode 100644 src/log4qt/src/log4qt/varia/nullappender.h delete mode 100644 src/log4qt/src/log4qt/varia/stringmatchfilter.cpp delete mode 100644 src/log4qt/src/log4qt/varia/stringmatchfilter.h delete mode 100644 src/log4qt/src/log4qt/writerappender.cpp delete mode 100644 src/log4qt/src/log4qt/writerappender.h diff --git a/src/log4qt/src/log4qt/appender.h b/src/log4qt/src/log4qt/appender.h deleted file mode 100644 index 81f6aa4..0000000 --- a/src/log4qt/src/log4qt/appender.h +++ /dev/null @@ -1,135 +0,0 @@ -/****************************************************************************** - * - * package: Log4Qt - * file: appender.h - * created: September 2007 - * author: Martin Heinrich - * - * - * Copyright 2007 Martin Heinrich - * - * 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. - * - ********************************************************************************/ - -#ifndef LOG4QT_APPENDER_H -#define LOG4QT_APPENDER_H - - -/****************************************************************************** - * Dependencies - ******************************************************************************/ - -#include "log4qt/helpers/logobject.h" - -#include "log4qt/helpers/logobjectptr.h" - -#include "log4qt/logger.h" - - -/****************************************************************************** - * Declarations - ******************************************************************************/ - -namespace Log4Qt -{ - - class Filter; - class Layout; - class LoggingEvent; - - /*! - * \brief The class Appender is the base class for all Appenders. - * - * To allow the whole hirarchy to be an ascendant of QObject Appender is - * not an interface. - * - * \note All the functions declared in this class are thread-safe. - * - * \note The ownership and lifetime of objects of this class are managed. - * See \ref Ownership "Object ownership" for more details. - */ - class Appender : public LogObject - { - Q_OBJECT - - /*! - * The property holds the Layout used by the Appender. - * - * \sa layout(), setLayout() - */ - Q_PROPERTY(Layout* layout READ layout WRITE setLayout) - - /*! - * The property holds the name of the Appender. - * - * \sa name(), setName() - */ - Q_PROPERTY(QString name READ name WRITE setName) - - /*! - * The property holds if the Appender requires a Layout or not. - * - * \sa requiresLayout(), setRequiresLayout() - */ - Q_PROPERTY(bool requiresLayout READ requiresLayout) - - public: - Appender(QObject *pParent = 0); - virtual ~Appender(); - private: - Appender(const Appender &rOther); // Not implemented - Appender &operator=(const Appender &rOther); // Not implemented - - public: - // JAVA: ErrorHandler* errorHandler(); - virtual Filter *filter() const = 0; - virtual QString name() const = 0; - virtual Layout *layout() const = 0; - virtual bool requiresLayout() const = 0; - // JAVA: void setErrorHandler(ErrorHandler *pErrorHandler); - virtual void setLayout(Layout *pLayout) = 0; - virtual void setName(const QString &rName) = 0; - - virtual void addFilter(Filter *pFilter) = 0; - virtual void clearFilters() = 0; - virtual void close() = 0; - virtual void doAppend(const LoggingEvent &rEvent) = 0; - }; - - - /************************************************************************** - * Operators, Helper - **************************************************************************/ - - - /************************************************************************** - * Inline - **************************************************************************/ - - inline Appender::Appender(QObject *pParent) : - LogObject(pParent) - {} - - inline Appender::~Appender() - {} - - -} // namespace Log4Qt - - -// Q_DECLARE_TYPEINFO(Log4Qt::Appender, Q_COMPLEX_TYPE); // Use default -Q_DECLARE_TYPEINFO(Log4Qt::LogObjectPtr, Q_MOVABLE_TYPE); - - -#endif // LOG4QT_APPENDER_H diff --git a/src/log4qt/src/log4qt/appenderskeleton.cpp b/src/log4qt/src/log4qt/appenderskeleton.cpp deleted file mode 100644 index d9f784b..0000000 --- a/src/log4qt/src/log4qt/appenderskeleton.cpp +++ /dev/null @@ -1,261 +0,0 @@ -/****************************************************************************** - * - * package: Log4Qt - * file: appenderskeleton.cpp - * created: September 2007 - * author: Martin Heinrich - * - * - * Copyright 2007 Martin Heinrich - * - * 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. - * - ******************************************************************************/ - - - -/****************************************************************************** - * Dependencies - ******************************************************************************/ - - -#include "log4qt/appenderskeleton.h" - -#include -#include "log4qt/layout.h" -#include "log4qt/loggingevent.h" -#include "log4qt/logmanager.h" -#include "log4qt/spi/filter.h" - - -namespace Log4Qt -{ - - - /************************************************************************** - * Declarations - ***************************************************************************/ - - - /*! - * \brief The class RecursionGuardLocker controls a boolean flag. - * - * It is a helper class to control a boolean flag. The class sets the flag - * on creation and resets it on destruction. - */ - class RecursionGuardLocker - { - public: - RecursionGuardLocker(bool *pGuard); - ~RecursionGuardLocker(); - private: - RecursionGuardLocker(const RecursionGuardLocker &rOther); // Not implemented - RecursionGuardLocker &operator=(const RecursionGuardLocker &rOther); // Not implemented - private: - bool *mpGuard; - }; - - - - /************************************************************************** - * C helper functions - **************************************************************************/ - - - - /************************************************************************** - * Class implementation: RecursionGuardLocker - ***************************************************************************/ - - - inline RecursionGuardLocker::RecursionGuardLocker(bool *pGuard) - { - Q_ASSERT_X(pGuard != 0, "RecursionGuardLocker::RecursionGuardLocker()", "Pointer to guard bool must not be null"); - - mpGuard = pGuard; - *mpGuard = true; - } - - - inline RecursionGuardLocker::~RecursionGuardLocker() - { - *mpGuard = false; - }; - - - - /************************************************************************** - * Class implementation: AppenderSkeleton - **************************************************************************/ - - - AppenderSkeleton::AppenderSkeleton(QObject *pParent) : - Appender(pParent), - mObjectGuard(QMutex::Recursive), // Recursive for doAppend() - mAppendRecursionGuard(false), - mIsActive(true), - mIsClosed(false), - mpLayout(0), - mThreshold(Level::NULL_INT), - mpHeadFilter(0), - mpTailFilter(0) - { - } - - - AppenderSkeleton::AppenderSkeleton(const bool isActive, - QObject *pParent) : - Appender(pParent), - mObjectGuard(QMutex::Recursive), // Recursive for doAppend() - mAppendRecursionGuard(false), - mIsActive(isActive), - mIsClosed(false), - mpLayout(0), - mThreshold(Level::NULL_INT), - mpHeadFilter(0), - mpTailFilter(0) - { - } - - - void AppenderSkeleton::activateOptions() - { - QMutexLocker locker(&mObjectGuard); - - if (requiresLayout() && !layout()) - { - LogError e = LOG4QT_QCLASS_ERROR(QT_TR_NOOP("Activation of appender '%1' that requires layout and has no layout set"), - APPENDER_ACTIVATE_MISSING_LAYOUT_ERROR); - e << name(); - logger()->error(e); - return; - } - mIsActive = true; - } - - - void AppenderSkeleton::addFilter(Filter *pFilter) - { - if(!pFilter) - { - logger()->warn("Adding null Filter to Appender '%1'", name()); - return; - } - - QMutexLocker locker(&mObjectGuard); - - mpTailFilter = pFilter; - if (mpHeadFilter) - mpHeadFilter->setNext(pFilter); - else - mpHeadFilter = pFilter; - } - - - void AppenderSkeleton::clearFilters() - { - QMutexLocker locker(&mObjectGuard); - - mpTailFilter = 0; - mpHeadFilter = 0; - } - - - void AppenderSkeleton::close() - { - QMutexLocker locker(&mObjectGuard); - - mIsClosed = true; - mIsActive = false; - } - - - void AppenderSkeleton::doAppend(const LoggingEvent &rEvent) - { - // The mutex serialises concurrent access from multiple threads. - // - e.g. two threads using the same logger - // - e.g. two threads using different logger with the same appender - // - // A call from the same thread will pass the mutex (QMutex::Recursive) - // and get to the recursion guard. The recursion guard blocks recursive - // invocation and prevents a possible endless loop. - // - e.g. an appender logs an error with a logger that uses it - - QMutexLocker locker(&mObjectGuard); - - if (mAppendRecursionGuard) - return; - - RecursionGuardLocker recursion_locker(&mAppendRecursionGuard); - - if (!checkEntryConditions()) - return; - if (!isAsSevereAsThreshold(rEvent.level())) - return; - - Filter *p_filter = mpHeadFilter; - while(p_filter) - { - Filter::Decision decision = p_filter->decide(rEvent); - if (decision == Filter::ACCEPT) - break; - else if (decision == Filter::DENY) - return; - else - p_filter = p_filter->next(); - } - - append(rEvent); - } - - - bool AppenderSkeleton::checkEntryConditions() const - { - // Q_ASSERT_X(, "WriterAppender::checkEntryConditions()", "Lock must be held by caller") - - if (!isActive()) - { - LogError e = LOG4QT_QCLASS_ERROR(QT_TR_NOOP("Use of non activated appender '%1'"), - APPENDER_NOT_ACTIVATED_ERROR); - e << name(); - logger()->error(e); - return false; - } - if (isClosed()) - { - LogError e = LOG4QT_QCLASS_ERROR(QT_TR_NOOP("Use of closed appender '%1'"), - APPENDER_CLOSED_ERROR); - e << name(); - logger()->error(e); - return false; - } - if (requiresLayout() && !layout()) - { - LogError e = LOG4QT_QCLASS_ERROR(QT_TR_NOOP("Use of appender '%1' that requires layout and has no layout set"), - APPENDER_USE_MISSING_LAYOUT_ERROR); - e << name(); - logger()->error(e); - return false; - } - - return true; - } - - - - /************************************************************************** - * Implementation: Operators, Helper - **************************************************************************/ - - -} // namespace Log4Qt diff --git a/src/log4qt/src/log4qt/appenderskeleton.h b/src/log4qt/src/log4qt/appenderskeleton.h deleted file mode 100644 index 6f252b3..0000000 --- a/src/log4qt/src/log4qt/appenderskeleton.h +++ /dev/null @@ -1,225 +0,0 @@ -/****************************************************************************** - * - * package: Log4Qt - * file: appenderskeleton.h - * created: September 2007 - * author: Martin Heinrich - * - * - * Copyright 2007 Martin Heinrich - * - * 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. - * - ******************************************************************************/ - -#ifndef LOG4QT_APPENDERSKELETON_H -#define LOG4QT_APPENDERSKELETON_H - - -/****************************************************************************** - * Dependencies -******************************************************************************/ - -#include "log4qt/appender.h" - -#include -#include "log4qt/helpers/logobjectptr.h" - - -/****************************************************************************** - * Declarations - ******************************************************************************/ - -namespace Log4Qt -{ - - class Filter; - class Layout; - class Logger; - class LoggingEvent; - - /*! - * \brief The class AppenderSkeleton implements general Appender functionality. - * - * \note All the functions declared in this class are thread-safe. - * - * \note The ownership and lifetime of objects of this class are managed. See - * \ref Ownership "Object ownership" for more details. - */ - class AppenderSkeleton : public Appender - { - Q_OBJECT - - /*! - * The property holds if the Appender has been activated. - * - * \sa isActive() - */ - Q_PROPERTY(bool isActive READ isActive) - - /*! - * The property holds if the Appender has been closed. - * - * \sa isClosed() - */ - Q_PROPERTY(bool isClosed READ isClosed) - - /*! - * The property holds the threshold level used by the Appender. - * - * \sa threshold(), setThreshold() - */ - Q_PROPERTY(Level threshold READ threshold WRITE setThreshold) - - public: - AppenderSkeleton(QObject *pParent = 0); - protected: - AppenderSkeleton(const bool isActive, - QObject *pParent = 0); - public: - // virtual ~AppenderSkeleton(); Use compiler default - private: - AppenderSkeleton(const AppenderSkeleton &rOther); // Not implemented - AppenderSkeleton &operator=(const AppenderSkeleton &rOther); // Not implemented - - public: - // JAVA: ErrorHandler* errorHandler(); - virtual Filter *filter() const; - virtual Layout *layout() const; - bool isActive() const; - bool isClosed() const; - virtual QString name() const; - Level threshold() const; - // JAVA: void setErrorHandler(ErrorHandler *pErrorHandler); - virtual void setLayout(Layout *pLayout); - virtual void setName(const QString &rName); - void setThreshold(Level level); - - virtual void activateOptions(); - virtual void addFilter(Filter *pFilter); - virtual void clearFilters(); - virtual void close(); - - /*! - * Performs checks and delegates the actuall appending to the subclass - * specific append() function. - * - * \sa append(), checkEntryConditions(), isAsSevereAsThreshold(), Filter - */ - virtual void doAppend(const LoggingEvent &rEvent); - - // JAVA: void finalize(); - Filter* firstFilter() const; - bool isAsSevereAsThreshold(Level level) const; - - protected: - virtual void append(const LoggingEvent &rEvent) = 0; - - /*! - * Tests if all entry conditions for using append() in this class are - * met. - * - * If a conditions is not met, an error is logged and the function - * returns false. - * - * The checked conditions are: - * - That the appender has been activated (APPENDER_NOT_ACTIVATED_ERROR) - * - That the appender was not closed (APPENDER_CLOSED_ERROR) - * - That the appender has a layout set, if it requires one - * (logging_error(APPENDER_USE_MISSING_LAYOUT_ERROR) - * - * The function is called as part of the checkEntryConditions() chain - * started by doAppend(). The doAppend() function calls the subclass - * specific checkEntryConditions() function. The function checks the - * class specific conditions and calls checkEntryConditions() of - * it's parent class. The last function called is - * AppenderSkeleton::checkEntryConditions(). - * - * \sa doAppend() - */ - virtual bool checkEntryConditions() const; - - protected: - mutable QMutex mObjectGuard; - private: - bool mAppendRecursionGuard; - volatile bool mIsActive; - volatile bool mIsClosed; - LogObjectPtr mpLayout; - Level mThreshold; - LogObjectPtr mpHeadFilter; - LogObjectPtr mpTailFilter; - }; - - - /************************************************************************** - * Operators, Helper - **************************************************************************/ - - - /************************************************************************** - * Inline - **************************************************************************/ - - inline Filter *AppenderSkeleton::filter() const - { QMutexLocker locker(&mObjectGuard); - return mpHeadFilter; } - - inline Layout *AppenderSkeleton::layout() const - { QMutexLocker locker(&mObjectGuard); - return mpLayout; } - - inline QString AppenderSkeleton::name() const - { QMutexLocker locker(&mObjectGuard); - return objectName(); } - - inline Level AppenderSkeleton::threshold() const - { // QMutexLocker locker(&mObjectGuard); // Level is threadsafe - return mThreshold; } - - inline void AppenderSkeleton::setLayout(Layout *pLayout) - { QMutexLocker locker(&mObjectGuard); - mpLayout = pLayout; } - - inline void AppenderSkeleton::setName(const QString &rName) - { QMutexLocker locker(&mObjectGuard); - setObjectName(rName); } - - inline void AppenderSkeleton::setThreshold(Level level) - { // QMutexLocker locker(&mObjectGuard); // Level is threadsafe - mThreshold = level; } - - inline bool AppenderSkeleton::isActive() const - { // QMutexLocker locker(&mObjectGuard); // Read/Write of int is safe - return mIsActive; } - - inline bool AppenderSkeleton::isClosed() const - { // QMutexLocker locker(&mObjectGuard); // Read/Write of int is safe - return mIsClosed; } - - inline Filter *AppenderSkeleton::firstFilter() const - { QMutexLocker locker(&mObjectGuard); - return filter(); } - - inline bool AppenderSkeleton::isAsSevereAsThreshold(Level level) const - { // QMutexLocker locker(&mObjectGuard); // Level is threadsafe - return (mThreshold <= level); } - - -} // namespace Log4Qt - - -// Q_DECLARE_TYPEINFO(Log4Qt::AppenderSkeleton, Q_COMPLEX_TYPE); // Use default - - -#endif // LOG4QT_APPENDERSKELETON_H diff --git a/src/log4qt/src/log4qt/basicconfigurator.cpp b/src/log4qt/src/log4qt/basicconfigurator.cpp deleted file mode 100644 index 280b88d..0000000 --- a/src/log4qt/src/log4qt/basicconfigurator.cpp +++ /dev/null @@ -1,107 +0,0 @@ -/****************************************************************************** - * - * package: Log4Qt - * file: basicconfigurator.cpp - * created: September 2007 - * author: Martin Heinrich - * - * - * Copyright 2007 Martin Heinrich - * - * 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. - * - ******************************************************************************/ - - - -/****************************************************************************** - * Dependencies - ******************************************************************************/ - - -#include "log4qt/basicconfigurator.h" - -#include -#include -#include -#include "log4qt/consoleappender.h" -#include "log4qt/helpers/configuratorhelper.h" -#include "log4qt/helpers/logobjectptr.h" -#include "log4qt/logmanager.h" -#include "log4qt/patternlayout.h" -#include "log4qt/varia/listappender.h" - - - -namespace Log4Qt -{ - - - /************************************************************************** - * Declarations - **************************************************************************/ - - - - /************************************************************************** - * C helper functions - **************************************************************************/ - - - - /************************************************************************** - * Class implementation: BasicConfigurator - **************************************************************************/ - - - bool BasicConfigurator::configure() - { - LogObjectPtr list = new ListAppender; - list->setName(QLatin1String("BasicConfigurator")); - list->setConfiguratorList(true); - list->setThreshold(Level::ERROR_INT); - LogManager::logLogger()->addAppender(list); - - PatternLayout *p_layout = new PatternLayout(PatternLayout::TTCC_CONVERSION_PATTERN); - p_layout->setName(QLatin1String("BasicConfigurator TTCC")); - p_layout->activateOptions(); - ConsoleAppender *p_appender = new ConsoleAppender(p_layout, ConsoleAppender::STDOUT_TARGET); - p_appender->setName(QLatin1String("BasicConfigurator stdout")); - p_appender->activateOptions(); - LogManager::rootLogger()->addAppender(p_appender); - - LogManager::logLogger()->removeAppender(list); - ConfiguratorHelper::setConfigureError(list->list()); - return (list->list().count() == 0); - } - - - void BasicConfigurator::configure(Appender *pAppender) - { - LogManager::rootLogger()->addAppender(pAppender); - } - - - void BasicConfigurator::resetConfiguration() - { - LogManager::resetConfiguration(); - } - - - - /************************************************************************** - * Implementation: Operators, Helper - **************************************************************************/ - - -} // namespace Log4Qt diff --git a/src/log4qt/src/log4qt/basicconfigurator.h b/src/log4qt/src/log4qt/basicconfigurator.h deleted file mode 100644 index c301501..0000000 --- a/src/log4qt/src/log4qt/basicconfigurator.h +++ /dev/null @@ -1,84 +0,0 @@ -/****************************************************************************** - * - * package: Log4Qt - * file: basicconfigurator.h - * created: September 2007 - * author: Martin Heinrich - * - * - * Copyright 2007 Martin Heinrich - * - * 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. - * - ******************************************************************************/ - -#ifndef LOG4QT_BASICCONFIGURATOR_H -#define LOG4QT_BASICCONFIGURATOR_H - - -/****************************************************************************** - * Dependencies - ******************************************************************************/ - - -#include -#include "log4qt/log4qt.h" - - -/****************************************************************************** - * Declarations - ******************************************************************************/ - -namespace Log4Qt -{ - - class Appender; - - /*! - * \brief The class BasicConfigurator provides a simple package - * configuration. - * - * \note All the functions declared in this class are thread-safe. - */ - class BasicConfigurator - { - private: - BasicConfigurator(); // Not implemented - // BasicConfigurator(const BasicConfigurator &rOther); // Use compiler default - // virtual ~BasicConfigurator(); // Use compiler default - // BasicConfigurator &operator=(const BasicConfigurator &rOther); // Use compiler default - - public: - static bool configure(); - static void configure(Appender *pAppender); - static void resetConfiguration(); - }; - - - /************************************************************************** - * Operators, Helper - **************************************************************************/ - - - /************************************************************************** - * Inline - **************************************************************************/ - - -} // namspace Log4Qt - - -// Q_DECLARE_TYPEINFO(Log4Qt::BasicConfigurator, Q_MOVABLE_TYPE); // Use default - - -#endif // LOG4QT_BASICCONFIGURATOR_H diff --git a/src/log4qt/src/log4qt/consoleappender.cpp b/src/log4qt/src/log4qt/consoleappender.cpp deleted file mode 100644 index 1b4fe03..0000000 --- a/src/log4qt/src/log4qt/consoleappender.cpp +++ /dev/null @@ -1,198 +0,0 @@ -/****************************************************************************** - * - * package: Log4Qt - * file: consoleappender.cpp - * created: September 2007 - * author: Martin Heinrich - * - * - * Copyright 2007 Martin Heinrich - * - * 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. - * - ******************************************************************************/ - - - -/****************************************************************************** - * Dependencies - ******************************************************************************/ - - -#include "log4qt/consoleappender.h" - -#include -#include -#include "log4qt/helpers/optionconverter.h" -#include "log4qt/layout.h" -#include "log4qt/loggingevent.h" - - - -namespace Log4Qt -{ - - - /************************************************************************** - * Declarations - **************************************************************************/ - - - - /************************************************************************** - * C helper functions - **************************************************************************/ - - - - /************************************************************************** - * Class implementation: ConsoleAppender - **************************************************************************/ - - - ConsoleAppender::ConsoleAppender(QObject *pParent) : - WriterAppender(pParent), - mTarget(STDOUT_TARGET), - mpTextStream(0) - { - } - - - ConsoleAppender::ConsoleAppender(Layout *pLayout, - QObject *pParent) : - WriterAppender(pLayout, pParent), - mTarget(STDOUT_TARGET), - mpTextStream(0) - { - } - - - ConsoleAppender::ConsoleAppender(Layout *pLayout, - const QString &rTarget, - QObject *pParent) : - WriterAppender(pLayout, pParent), - mTarget(STDOUT_TARGET), - mpTextStream(0) - { - setTarget(rTarget); - } - - - ConsoleAppender::ConsoleAppender(Layout *pLayout, - Target target, - QObject *pParent) : - WriterAppender(pLayout, pParent), - mTarget(target), - mpTextStream(0) - { - } - - - ConsoleAppender::~ConsoleAppender() - { - close(); - } - - - QString ConsoleAppender::target() const - { - // QMutexLocker locker(&mObjectGuard); // Read/Write of int is safe - - if (mTarget == STDOUT_TARGET) - return QLatin1String("STDOUT_TARGET"); - else - return QLatin1String("STDERR_TARGET"); - } - - - void ConsoleAppender::setTarget(const QString &rTarget) - { - bool ok; - Target target = (Target)OptionConverter::toTarget(rTarget, &ok); - if (ok) - setTarget(target); - } - - - void ConsoleAppender::activateOptions() - { - QMutexLocker locker(&mObjectGuard); - - closeStream(); - - if (mTarget == STDOUT_TARGET) - mpTextStream = new QTextStream(stdout); - else - mpTextStream = new QTextStream(stderr); - setWriter(mpTextStream); - - WriterAppender::activateOptions(); - } - - - void ConsoleAppender::close() - { - QMutexLocker locker(&mObjectGuard); - - if (isClosed()) - return; - - WriterAppender::close(); - closeStream(); - } - - - void ConsoleAppender::closeStream() - { - // Q_ASSERT_X(, "ConsoleAppender::closeStream()", "Lock must be held by caller") - - setWriter(0); - delete mpTextStream; - mpTextStream = 0; - } - - -#ifndef QT_NO_DEBUG_STREAM - QDebug ConsoleAppender::debug(QDebug &rDebug) const - { - QString layout_name; - if (layout()) - layout_name = layout()->name(); - QString target; - if (mTarget == STDOUT_TARGET) - target = QLatin1String("STDOUT"); - else - target = QLatin1String("STDERR"); - - rDebug.nospace() << "ConsoleAppender(" - << "name:" << name() << " " - << "filter:" << firstFilter() << " " - << "isactive:" << isActive() << " " - << "isclosed:" << isClosed() << " " - << "layout:" << layout_name << " " - << "target:" << target << " " - << "referencecount:" << referenceCount() << " " - << "threshold:" << threshold().toString() - << ")"; - return rDebug.space(); - } -#endif // QT_NO_DEBUG_STREAM - - - - /****************************************************************************** - * Implementation: Operators, Helper - ******************************************************************************/ - - -} // namespace Log4Qt diff --git a/src/log4qt/src/log4qt/consoleappender.h b/src/log4qt/src/log4qt/consoleappender.h deleted file mode 100644 index 466015d..0000000 --- a/src/log4qt/src/log4qt/consoleappender.h +++ /dev/null @@ -1,160 +0,0 @@ -/****************************************************************************** - * - * package: Log4Qt - * file: consoleappender.h - * created: September 2007 - * author: Martin Heinrich - * - * - * Copyright 2007 Martin Heinrich - * - * 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. - * - ******************************************************************************/ - -#ifndef LOG4QT_CONSOLEAPPENDER_H -#define LOG4QT_CONSOLEAPPENDER_H - - -/****************************************************************************** - * Dependencies - ******************************************************************************/ - -#include "log4qt/writerappender.h" - - -/****************************************************************************** - * Declarations - ******************************************************************************/ - -class QFile; -class QTextStream; - -namespace Log4Qt -{ - - /*! - * \brief The class ConsoleAppender appends to stdout or stderr. - * - * \note All the functions declared in this class are thread-safe. - * - * \note The ownership and lifetime of objects of this class are managed. - * See \ref Ownership "Object ownership" for more details. - */ - class ConsoleAppender : public WriterAppender - { - Q_OBJECT - - /*! - * The property holds the target used by the appender. - * - * The default is STDOUT_TARGET for the standard output. - * - * \sa Target, target(), setTarget() - */ - Q_PROPERTY(QString target READ target WRITE setTarget) - - public: - /*! - * The enum defines the possible output targets - * - * \sa target(), setTarget() - */ - enum Target { - /*! The output target is standard out. */ - STDOUT_TARGET, - /*! The output target is standard error. */ - STDERR_TARGET - }; - Q_ENUMS(Target) - - ConsoleAppender(QObject *pParent = 0); - ConsoleAppender(Layout *pLayout, - QObject *pParent = 0); - ConsoleAppender(Layout *pLayout, - const QString &rTarget, - QObject *pParent = 0); - - /*! - * Creates a ConsoleAppender with the layout \a pLayout, the target - * value specified by the \a target constant and the parent - * \a pParent. - */ - ConsoleAppender(Layout *pLayout, - Target target, - QObject *pParent = 0); - - virtual ~ConsoleAppender(); - private: - ConsoleAppender(const ConsoleAppender &rOther); // Not implemented - ConsoleAppender &operator=(const ConsoleAppender &rOther); // Not implemented - - public: - // JAVA: bool follow() const; - QString target() const; - // JAVA: void setFollow(bool follow); - void setTarget(const QString &rTarget); - - /*! - * Sets the target to the value specified by the \a target constant. - */ - void setTarget(Target target); - - virtual void activateOptions(); - virtual void close(); - - protected: - void closeStream(); - - #ifndef QT_NO_DEBUG_STREAM - /*! - * Writes all object member variables to the given debug stream - * \a rDebug and returns the stream. - * - * - * %ConsoleAppender(name:"CA" filter:0x0 isactive:true isclosed:false - * layout:"PL" target:"STDERR" referenceCount:1 - * threshold:"WARN_SET") - * - * \sa QDebug, operator<<(QDebug debug, const LogObject &rLogObject) - */ - virtual QDebug debug(QDebug &rDebug) const; - #endif // QT_NO_DEBUG_STREAM - - private: - volatile Target mTarget; - QTextStream *mpTextStream; - }; - - - /************************************************************************** - * Operators, Helper - **************************************************************************/ - - - /************************************************************************** - * Inline - **************************************************************************/ - - inline void ConsoleAppender::setTarget(Target target) - { // QMutexLocker locker(&mObjectGuard); // Read/Write of int is safe - mTarget = target; } - - -} // namespace Log4Qt - - -// Q_DECLARE_TYPEINFO(Log4Qt::ConsoleAppender, Q_COMPLEX_TYPE); // Use default - - -#endif // LOG4QT_CONSOLEAPPENDER_H diff --git a/src/log4qt/src/log4qt/dailyrollingfileappender.cpp b/src/log4qt/src/log4qt/dailyrollingfileappender.cpp deleted file mode 100644 index 0590f16..0000000 --- a/src/log4qt/src/log4qt/dailyrollingfileappender.cpp +++ /dev/null @@ -1,352 +0,0 @@ -/****************************************************************************** - * - * package: Log4Qt - * file: dailyrollingfileappender.cpp - * created: September 2007 - * author: Martin Heinrich - * - * - * Copyright 2007 Martin Heinrich - * - * 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. - * - ******************************************************************************/ - - - -/****************************************************************************** - * Dependencies - ******************************************************************************/ - - -#include "log4qt/dailyrollingfileappender.h" - -#include -#include -#include -#include -#include "log4qt/helpers/datetime.h" -#include "log4qt/layout.h" -#include "log4qt/loggingevent.h" - - - -namespace Log4Qt -{ - - - /************************************************************************** - * Declarations - **************************************************************************/ - - - - /************************************************************************** - * C helper functions - **************************************************************************/ - - - - /************************************************************************** - * Class implementation: DailyRollingFileAppender - **************************************************************************/ - - - DailyRollingFileAppender::DailyRollingFileAppender(QObject *pParent) : - FileAppender(pParent), - mDatePattern() - { - setDatePattern(DAILY_ROLLOVER); - } - - - DailyRollingFileAppender::DailyRollingFileAppender(Layout *pLayout, - const QString &rFileName, - const QString &rDatePattern, - QObject *pParent) : - FileAppender(pLayout, rFileName, pParent), - mDatePattern() - { - setDatePattern(rDatePattern); - } - - - DailyRollingFileAppender::~DailyRollingFileAppender() - { - close(); - } - - - void DailyRollingFileAppender::setDatePattern(DatePattern datePattern) - { - switch (datePattern) - { - case MINUTELY_ROLLOVER: - setDatePattern(QLatin1String("'.'yyyy-MM-dd-hh-mm")); - break; - case HOURLY_ROLLOVER: - setDatePattern(QLatin1String("'.'yyyy-MM-dd-hh")); - break; - case HALFDAILY_ROLLOVER: - setDatePattern(QLatin1String("'.'yyyy-MM-dd-a")); - break; - case DAILY_ROLLOVER: - setDatePattern(QLatin1String("'.'yyyy-MM-dd")); - break; - case WEEKLY_ROLLOVER: - setDatePattern(QLatin1String("'.'yyyy-ww")); - break; - case MONTHLY_ROLLOVER: - setDatePattern(QLatin1String("'.'yyyy-MM")); - break; - default: - Q_ASSERT_X(false, "DailyRollingFileAppender::setDatePattern()", "Invalid datePattern constant"); - setDatePattern(DAILY_ROLLOVER); - }; - } - - - void DailyRollingFileAppender::activateOptions() - { - QMutexLocker locker(&mObjectGuard); - - computeFrequency(); - if (!mActiveDatePattern.isEmpty()) - { - computeRollOverTime(); - FileAppender::activateOptions(); - } - } - - - void DailyRollingFileAppender::append(const LoggingEvent &rEvent) - { - // Q_ASSERT_X(, "DailyRollingFileAppender::append()", "Lock must be held by caller") - - if (QDateTime::currentDateTime() > mRollOverTime) - rollOver(); - FileAppender::append(rEvent); - } - - - bool DailyRollingFileAppender::checkEntryConditions() const - { - // Q_ASSERT_X(, "DailyRollingFileAppender::checkEntryConditions()", "Lock must be held by caller") - - if (mActiveDatePattern.isEmpty()) - { - LogError e = LOG4QT_QCLASS_ERROR(QT_TR_NOOP("Use of appender '%1' without having a valid date pattern set"), - APPENDER_USE_INVALID_PATTERN_ERROR); - e << name(); - logger()->error(e); - return false; - } - - return FileAppender::checkEntryConditions(); - } - - -#ifndef QT_NO_DEBUG_STREAM - QDebug DailyRollingFileAppender::debug(QDebug &rDebug) const - { - QString layout_name; - if (layout()) - layout_name = layout()->name(); - QString codec_name; - if (encoding()) - codec_name = QLatin1String(encoding()->name()); - - rDebug.nospace() << "DailyRollingFileAppender(" - << "name:" << name() << " " - << "activedatepattern:" << mActiveDatePattern << " " - << "appendfile:" << appendFile() << " " - << "bufferedio:" << bufferedIo() << " " - << "datepattern:" << datePattern() << " " - << "encoding:" << codec_name << " " - << "frequency:" << frequencyToString() << " " - << "file:" << file() << " " - << "filter:" << firstFilter() << " " - << "immediateflush:" << immediateFlush() << " " - << "isactive:" << isActive() << " " - << "isclosed:" << isClosed() << " " - << "layout:" << layout_name << " " - << "referencecount:" << referenceCount() << " " - << "rollovertime:" << mRollOverTime - << "threshold:" << threshold().toString() - << "writer:" << writer() - << ")"; - return rDebug.space(); - } -#endif // QT_NO_DEBUG_STREAM - - - void DailyRollingFileAppender::computeFrequency() - { - // Q_ASSERT_X(, "DailyRollingFileAppender::computeFrequency()", "Lock must be held by caller") - - const DateTime start_time(QDate(1999, 1, 1), QTime(0, 0)); - const QString start_string = start_time.toString(mDatePattern); - mActiveDatePattern.clear(); - - if (start_string != static_cast(start_time.addSecs(60)).toString(mDatePattern)) - mFrequency = MINUTELY_ROLLOVER; - else if (start_string != static_cast(start_time.addSecs(60 * 60)).toString(mDatePattern)) - mFrequency = HOURLY_ROLLOVER; - else if (start_string != static_cast(start_time.addSecs(60 * 60 * 12)).toString(mDatePattern)) - mFrequency = HALFDAILY_ROLLOVER; - else if (start_string != static_cast(start_time.addDays(1)).toString(mDatePattern)) - mFrequency = DAILY_ROLLOVER; - else if (start_string != static_cast(start_time.addDays(7)).toString(mDatePattern)) - mFrequency = WEEKLY_ROLLOVER; - else if (start_string != static_cast(start_time.addMonths(1)).toString(mDatePattern)) - mFrequency = MONTHLY_ROLLOVER; - else - { - LogError e = LOG4QT_QCLASS_ERROR(QT_TR_NOOP("The pattern '%1' does not specify a frequency for appender '%2'"), - APPENDER_INVALID_PATTERN_ERROR); - e << mDatePattern << name(); - logger()->error(e); - return; - } - - mActiveDatePattern = mDatePattern; - logger()->trace("Frequency set to %2 using date pattern %1", - mActiveDatePattern, - frequencyToString()); - } - - - void DailyRollingFileAppender::computeRollOverTime() - { - // Q_ASSERT_X(, "DailyRollingFileAppender::computeRollOverTime()", "Lock must be held by caller") - Q_ASSERT_X(!mActiveDatePattern.isEmpty(), "DailyRollingFileAppender::computeRollOverTime()", "No active date pattern"); - - QDateTime now = QDateTime::currentDateTime(); - QDate now_date = now.date(); - QTime now_time = now.time(); - QDateTime start; - - switch (mFrequency) - { - case MINUTELY_ROLLOVER: - { - start = QDateTime(now_date, - QTime(now_time.hour(), - now_time.minute(), - 0, 0)); - mRollOverTime = start.addSecs(60); - } - break; - case HOURLY_ROLLOVER: - { - start = QDateTime(now_date, - QTime(now_time.hour(), - 0, 0, 0)); - mRollOverTime = start.addSecs(60*60); - } - break; - case HALFDAILY_ROLLOVER: - { - int hour = now_time.hour(); - if (hour >= 12) - hour = 12; - else - hour = 0; - start = QDateTime(now_date, - QTime(hour, 0, 0, 0)); - mRollOverTime = start.addSecs(60*60*12); - } - break; - case DAILY_ROLLOVER: - { - start = QDateTime(now_date, - QTime(0, 0, 0, 0)); - mRollOverTime = start.addDays(1); - } - break; - case WEEKLY_ROLLOVER: - { - // QT numbers the week days 1..7. The week starts on Monday. - // Change it to being numbered 0..6, starting with Sunday. - int day = now_date.dayOfWeek(); - if (day == Qt::Sunday) - day = 0; - start = QDateTime(now_date, - QTime(0, 0, 0, 0)).addDays(-1 * day); - mRollOverTime = start.addDays(7); - } - break; - case MONTHLY_ROLLOVER: - { - start = QDateTime(QDate(now_date.year(), - now_date.month(), - 1), - QTime(0, 0, 0, 0)); - mRollOverTime = start.addMonths(1); - } - break; - default: - Q_ASSERT_X(false, "DailyRollingFileAppender::computeInterval()", "Invalid datePattern constant"); - mRollOverTime = QDateTime::fromTime_t(0); - } - - mRollOverSuffix = static_cast(start).toString(mActiveDatePattern); - Q_ASSERT_X(static_cast(now).toString(mActiveDatePattern) == mRollOverSuffix, - "DailyRollingFileAppender::computeRollOverTime()", "File name changes within interval"); - Q_ASSERT_X(mRollOverSuffix != static_cast(mRollOverTime).toString(mActiveDatePattern), - "DailyRollingFileAppender::computeRollOverTime()", "File name does not change with rollover"); - - logger()->trace("Computing roll over time from %1: The interval start time is %2. The roll over time is %3", - now, - start, - mRollOverTime); - } - - - QString DailyRollingFileAppender::frequencyToString() const - { - QMetaEnum meta_enum = metaObject()->enumerator(metaObject()->indexOfEnumerator("DatePattern")); - return QLatin1String(meta_enum.valueToKey(mFrequency)); - } - - - void DailyRollingFileAppender::rollOver() - { - // Q_ASSERT_X(, "DailyRollingFileAppender::rollOver()", "Lock must be held by caller") - Q_ASSERT_X(!mActiveDatePattern.isEmpty(), "DailyRollingFileAppender::rollOver()", "No active date pattern"); - - QString roll_over_suffix = mRollOverSuffix; - computeRollOverTime(); - if (roll_over_suffix == mRollOverSuffix) - return; - - closeFile(); - - QString target_file_name = file() + roll_over_suffix; - QFile f(target_file_name); - if (f.exists() && !removeFile(f)) - return; - f.setFileName(file()); - if (!renameFile(f, target_file_name)) - return; - openFile(); - } - - - - /************************************************************************** - * Implementation: Operators, Helper - **************************************************************************/ - - -} // namespace Log4Qt diff --git a/src/log4qt/src/log4qt/dailyrollingfileappender.h b/src/log4qt/src/log4qt/dailyrollingfileappender.h deleted file mode 100644 index e3fe638..0000000 --- a/src/log4qt/src/log4qt/dailyrollingfileappender.h +++ /dev/null @@ -1,196 +0,0 @@ -/****************************************************************************** - * - * package: Log4Qt - * file: dailyrollingfileappender.h - * created: September 2007 - * author: Martin Heinrich - * - * - * Copyright 2007 Martin Heinrich - * - * 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. - * - ******************************************************************************/ - -#ifndef LOG4QT_DAILYROLLINGFILEAPPENDER_H -#define LOG4QT_DAILYROLLINGFILEAPPENDER_H - - -/****************************************************************************** - * Dependencies - ******************************************************************************/ - -#include "log4qt/fileappender.h" - -#include - - -/****************************************************************************** - * Declarations - ******************************************************************************/ - -namespace Log4Qt -{ - - /*! - * \brief The class DailyRollingFileAppender extends FileAppender so that the - * underlying file is rolled over at a specified frequency. - * - * \note All the functions declared in this class are thread-safe. - * - * \note The ownership and lifetime of objects of this class are managed. See - * \ref Ownership "Object ownership" for more details. - */ - class DailyRollingFileAppender : public FileAppender - { - Q_OBJECT - - /*! - * The property holds the date pattern used by the appender. - * - * The default is DAILY_ROLLOVER for rollover at midnight each day. - * - * \sa datePattern(), setDatePattern() - */ - Q_PROPERTY(QString datePattern READ datePattern WRITE setDatePattern) - - public: - /*! - * The enum DatePattern defines constants for date patterns. - * - * \sa setDatePattern(DatePattern) - */ - enum DatePattern - { - /*! The minutely date pattern string is "'.'yyyy-MM-dd-hh-mm". */ - MINUTELY_ROLLOVER = 0, - /*! The hourly date pattern string is "'.'yyyy-MM-dd-hh". */ - HOURLY_ROLLOVER, - /*! The half-daily date pattern string is "'.'yyyy-MM-dd-a". */ - HALFDAILY_ROLLOVER, - /*! The daily date pattern string is "'.'yyyy-MM-dd". */ - DAILY_ROLLOVER, - /*! The weekly date pattern string is "'.'yyyy-ww". */ - WEEKLY_ROLLOVER, - /*! The monthly date pattern string is "'.'yyyy-MM". */ - MONTHLY_ROLLOVER - }; - Q_ENUMS(DatePattern) - - DailyRollingFileAppender(QObject *pParent = 0); - DailyRollingFileAppender(Layout *pLayout, - const QString &rFileName, - const QString &rDatePattern, - QObject *pParent = 0); - virtual ~DailyRollingFileAppender(); - private: - DailyRollingFileAppender(const DailyRollingFileAppender &rOther); // Not implemented - DailyRollingFileAppender &operator=(const DailyRollingFileAppender &rOther); // Not implemented - - public: - QString datePattern() const; - - /*! - * Sets the datePattern to the value specified by the \a datePattern - * constant. - */ - void setDatePattern(DatePattern datePattern); - - void setDatePattern(const QString &rDatePattern); - - virtual void activateOptions(); - - protected: - virtual void append(const LoggingEvent &rEvent); - - /*! - * Tests if all entry conditions for using append() in this class are - * met. - * - * If a conditions is not met, an error is logged and the function - * returns false. Otherwise the result of - * FileAppender::checkEntryConditions() is returned. - * - * The checked conditions are: - * - A valid pattern has been set (APPENDER_USE_INVALID_PATTERN_ERROR) - * - * The function is called as part of the checkEntryConditions() chain - * started by AppenderSkeleton::doAppend(). - * - * \sa AppenderSkeleton::doAppend(), - * AppenderSkeleton::checkEntryConditions() - */ - virtual bool checkEntryConditions() const; - - protected: -#ifndef QT_NO_DEBUG_STREAM - /*! - * Writes all object member variables to the given debug stream - * \a rDebug and returns the stream. - * - * - * %DailyRollingFileAppender(name:"DRFA" activedatepattern:"'.'yyyy-MM-dd-hh-mm" - * appendfile:false bufferedio:true - * datepattern:"'.'yyyy-MM-dd-hh-mm" - * encoding:"" frequency:"MINUTELY_ROLLOVER" - * file:"/log.txt" filter:0x0 immediateflush:true - * isactive:true isclosed:false layout:"TTCC" - * referencecount:1 - * rollovertime:QDateTime("Mon Oct 22 05:23:00 2007") - * threshold: "NULL" writer: 0x0 ) - * - * \sa QDebug, operator<<(QDebug debug, const LogObject &rLogObject) - */ - virtual QDebug debug(QDebug &rDebug) const; -#endif // QT_NO_DEBUG_STREAM - - private: - void computeFrequency(); - void computeRollOverTime(); - QString frequencyToString() const; - void rollOver(); - - private: - QString mDatePattern; - DatePattern mFrequency; - QString mActiveDatePattern; - QDateTime mRollOverTime; - QString mRollOverSuffix; - }; - - - /************************************************************************** - * Operators, Helper - **************************************************************************/ - - - /************************************************************************** - * Inline - **************************************************************************/ - - inline QString DailyRollingFileAppender::datePattern() const - { QMutexLocker locker(&mObjectGuard); - return mDatePattern; } - - inline void DailyRollingFileAppender::setDatePattern(const QString &rDatePattern) - { QMutexLocker locker(&mObjectGuard); - mDatePattern = rDatePattern; } - - -} // namespace Log4Qt - - -// Q_DECLARE_TYPEINFO(Log4Qt::DailyRollingFileAppender, Q_COMPLEX_TYPE); // Use default - - -#endif // LOG4QT_DAILYROLLINGFILEAPPENDER_H diff --git a/src/log4qt/src/log4qt/fileappender.cpp b/src/log4qt/src/log4qt/fileappender.cpp deleted file mode 100644 index 265634f..0000000 --- a/src/log4qt/src/log4qt/fileappender.cpp +++ /dev/null @@ -1,307 +0,0 @@ -/****************************************************************************** - * - * package: Log4Qt - * file: fileappender.cpp - * created: September 2007 - * author: Martin Heinrich - * - * - * Copyright 2007 Martin Heinrich - * - * 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. - * - ******************************************************************************/ - - - -/****************************************************************************** - * Dependencies - ******************************************************************************/ - - -#include "log4qt/fileappender.h" - -#include -#include -#include -#include -#include -#include -#include "log4qt/layout.h" -#include "log4qt/loggingevent.h" - - - -namespace Log4Qt -{ - - - /************************************************************************** - * Declarations - **************************************************************************/ - - - - /************************************************************************** - * C helper functions - **************************************************************************/ - - - - /************************************************************************** - * Class implementation: FileAppender - **************************************************************************/ - - - FileAppender::FileAppender(QObject *pParent) : - WriterAppender(pParent), - mAppendFile(false), - mBufferedIo(true), - mFileName(), - mpFile(0), - mpTextStream(0) - { - } - - - FileAppender::FileAppender(Layout *pLayout, - const QString &rFileName, - QObject *pParent) : - WriterAppender(pLayout, pParent), - mAppendFile(false), - mBufferedIo(true), - mFileName(rFileName), - mpFile(0), - mpTextStream(0) - { - } - - - FileAppender::FileAppender(Layout *pLayout, - const QString &rFileName, - bool append, - QObject *pParent) : - WriterAppender(pLayout, pParent), - mAppendFile(append), - mBufferedIo(true), - mFileName(rFileName), - mpFile(0), - mpTextStream(0) - { - } - - - FileAppender::FileAppender(Layout *pLayout, - const QString &rFileName, - bool append, - bool buffered, - QObject *pParent) : - WriterAppender(pLayout, pParent), - mAppendFile(append), - mBufferedIo(buffered), - mFileName(rFileName), - mpFile(0), - mpTextStream(0) - { - } - - - FileAppender::~FileAppender() - { - close(); - } - - - void FileAppender::activateOptions() - { - QMutexLocker locker(&mObjectGuard); - - if (mFileName.isEmpty()) - { - LogError e = LOG4QT_QCLASS_ERROR(QT_TR_NOOP("Activation of Appender '%1' that requires file and has no file set"), - APPENDER_ACTIVATE_MISSING_FILE_ERROR); - e << name(); - logger()->error(e); - return; - } - closeFile(); - openFile(); - WriterAppender::activateOptions(); - } - - - void FileAppender::close() - { - QMutexLocker locker(&mObjectGuard); - - if (isClosed()) - return; - - WriterAppender::close(); - closeFile(); - } - - - bool FileAppender::checkEntryConditions() const - { - // Q_ASSERT_X(, "FileAppender::checkEntryConditions()", "Lock must be held by caller") - - if (!mpFile || !mpTextStream) - { - LogError e = LOG4QT_QCLASS_ERROR(QT_TR_NOOP("Use of appender '%1' without open file"), - APPENDER_NO_OPEN_FILE_ERROR); - e << name(); - logger()->error(e); - return false; - } - - return WriterAppender::checkEntryConditions(); - } - - - void FileAppender::closeFile() - { - // Q_ASSERT_X(, "FileAppender::closeFile()", "Lock must be held by caller") - - if (mpFile) - logger()->debug("Closing file '%1' for appender '%2'", mpFile->fileName(), name()); - - setWriter(0); - delete mpTextStream; - mpTextStream = 0; - delete mpFile; - mpFile = 0; - } - - -#ifndef QT_NO_DEBUG_STREAM - QDebug FileAppender::debug(QDebug &rDebug) const - { - QString layout_name; - if (layout()) - layout_name = layout()->name(); - QString codec_name; - if (encoding()) - codec_name = QLatin1String(encoding()->name()); - - rDebug.nospace() << "FileAppender(" - << "name:" << name() << " " - << "appendfile:" << appendFile() << " " - << "bufferedio:" << bufferedIo() << " " - << "encoding:" << codec_name << " " - << "file:" << file() << " " - << "filter:" << firstFilter() << " " - << "immediateflush:" << immediateFlush() << " " - << "isactive:" << isActive() << " " - << "isclosed:" << isClosed() << " " - << "layout:" << layout_name << " " - << "referencecount:" << referenceCount() << " " - << "threshold:" << threshold().toString() << " " - << "writer:" << writer() - << ")"; - return rDebug.space(); - } -#endif // QT_NO_DEBUG_STREAM - - - bool FileAppender::handleIoErrors() const - { - // Q_ASSERT_X(, "FileAppender::handleIoErrors()", "Lock must be held by caller") - - if (mpFile->error() == QFile::NoError) - return false; - - LogError e = LOG4QT_QCLASS_ERROR(QT_TR_NOOP("Unable to write to file '%1' for appender '%2'"), - APPENDER_WRITING_FILE_ERROR); - e << mFileName << name(); - e.addCausingError(LogError(mpFile->errorString(), mpFile->error())); - logger()->error(e); - return true; - } - - - void FileAppender::openFile() - { - Q_ASSERT_X(mpFile == 0 && mpTextStream == 0, "FileAppender::openFile()", "Opening file without closing previous file"); - - QFileInfo file_info(mFileName); - QDir parent_dir = file_info.dir(); - if (!parent_dir.exists()) - { - logger()->trace("Creating missing parent directory for file %1", mFileName); - QString name = parent_dir.dirName(); - parent_dir.cdUp(); - parent_dir.mkdir(name); - } - - - mpFile = new QFile(mFileName); - QFile::OpenMode mode = QIODevice::WriteOnly | QIODevice::Text; - if (mAppendFile) - mode |= QIODevice::Append; - else - mode |= QIODevice::Truncate; - if (!mBufferedIo) - mode |= QIODevice::Unbuffered; - if (!mpFile->open(mode)) - { - LogError e = LOG4QT_QCLASS_ERROR(QT_TR_NOOP("Unable to open file '%1' for appender '%2'"), - APPENDER_OPENING_FILE_ERROR); - e << mFileName << name(); - e.addCausingError(LogError(mpFile->errorString(), mpFile->error())); - logger()->error(e); - return; - } - mpTextStream = new QTextStream(mpFile); - setWriter(mpTextStream); - logger()->debug("Opened file '%1' for appender '%2'", mpFile->fileName(), name()); - } - - - bool FileAppender::removeFile(QFile &rFile) const - { - if (rFile.remove()) - return true; - - LogError e = LOG4QT_QCLASS_ERROR(QT_TR_NOOP("Unable to remove file '%1' for appender '%2'"), - APPENDER_REMOVE_FILE_ERROR); - e << rFile.fileName() << name(); - e.addCausingError(LogError(rFile.errorString(), rFile.error())); - logger()->error(e); - return false; - } - - - bool FileAppender::renameFile(QFile &rFile, - const QString &rFileName) const - { - logger()->debug("Renaming file '%1' to '%2'", rFile.fileName(), rFileName); - if (rFile.rename(rFileName)) - return true; - - LogError e = LOG4QT_QCLASS_ERROR(QT_TR_NOOP("Unable to rename file '%1' to '%2' for appender '%3'"), - APPENDER_RENAMING_FILE_ERROR); - e << rFile.fileName() << rFileName << name(); - e.addCausingError(LogError(rFile.errorString(), rFile.error())); - logger()->error(e); - return false; - } - - - - /************************************************************************** - * Implementation: Operators, Helper - **************************************************************************/ - - -} // namespace Log4Qt diff --git a/src/log4qt/src/log4qt/fileappender.h b/src/log4qt/src/log4qt/fileappender.h deleted file mode 100644 index 2479d4e..0000000 --- a/src/log4qt/src/log4qt/fileappender.h +++ /dev/null @@ -1,233 +0,0 @@ -/****************************************************************************** - * - * package: Log4Qt - * file: fileappender.h - * created: September 2007 - * author: Martin Heinrich - * - * - * Copyright 2007 Martin Heinrich - * - * 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. - * - ******************************************************************************/ - -#ifndef LOG4QT_FILEAPPENDER_H -#define LOG4QT_FILEAPPENDER_H - - -/****************************************************************************** - * Dependencies - ******************************************************************************/ - -#include "log4qt/writerappender.h" - - -/****************************************************************************** - * Declarations - ******************************************************************************/ - -class QFile; -class QTextStream; - -namespace Log4Qt -{ - - /*! - * \brief The class FileAppender appends log events to a file. - * - * \note All the functions declared in this class are thread-safe. - * - * \note The ownership and lifetime of objects of this class are managed. See - * \ref Ownership "Object ownership" for more details. - */ - class FileAppender : public WriterAppender - { - Q_OBJECT - - /*! - * The property holds, if the output is appended to the file. - * - * The default is false for not appending. - * - * \sa appendFile(), setAppendFile() - */ - Q_PROPERTY(bool appendFile READ appendFile WRITE setAppendFile) - - /*! - * The property holds, if the output is buffered. - * - * The default is true for buffering. - * - * \sa bufferedIo(), setBufferedIo() - */ - Q_PROPERTY(bool bufferedIo READ bufferedIo WRITE setBufferedIo) - - /*! - * The property holds the name of the file. - * - * \sa file(), setFile() - */ - Q_PROPERTY(QString file READ file WRITE setFile) - - public: - FileAppender(QObject *pParent = 0); - FileAppender(Layout *pLayout, - const QString &rFileName, - QObject *pParent = 0); - FileAppender(Layout *pLayout, - const QString &rFileName, - bool append, - QObject *pParent = 0); - FileAppender(Layout *pLayout, - const QString &rFileName, - bool append, - bool buffered, - QObject *pParent = 0); - virtual ~FileAppender(); - private: - FileAppender(const FileAppender &rOther); // Not implemented - FileAppender &operator=(const FileAppender &rOther); // Not implemented - - public: - bool appendFile() const; - QString file() const; - bool bufferedIo() const; - // JAVA: int bufferSize() const; - void setAppendFile(bool append); - void setBufferedIo(bool buffered); - // JAVA: void setBufferSize(int bufferSize); - void setFile(const QString &rFileName); - - virtual void activateOptions(); - virtual void close(); - - protected: - /*! - * Tests if all entry conditions for using append() in this class are met. - * - * If a conditions is not met, an error is logged and the function returns - * false. Otherwise the result of WriterAppender::checkEntryConditions() - * is returned. - * - * The checked conditions are: - * - That a file is set and open (APPENDER_NO_OPEN_FILE_ERROR) - * - * The function is called as part of the checkEntryConditions() chain - * started by AppenderSkeleton::doAppend(). - * - * \sa AppenderSkeleton::doAppend(), AppenderSkeleton::checkEntryConditions() - */ - virtual bool checkEntryConditions() const; - - void closeFile(); - -#ifndef QT_NO_DEBUG_STREAM - /*! - * Writes all object member variables to the given debug stream \a rDebug - * and returns the stream. - * - * - * %FileAppender(name:"FA" appendfile:false bufferedio:true encoding:"" - * file:"/log.txt" filter: 0x0 immediateflush:true isactive:false - * isclosed:false layout:"TTCC" referencecount:2 - * threshold:"NULL" writer:0x0) - * - * \sa QDebug, operator<<(QDebug debug, const LogObject &rLogObject) - */ - virtual QDebug debug(QDebug &rDebug) const; -#endif // QT_NO_DEBUG_STREAM - - /*! - * Checks for file I/O errrors. If an error is found it is logged and the - * function returns true. Otherwise false is returned. - */ - virtual bool handleIoErrors() const; - - /*! - * Opens the file for the appender based on the specified file name and - * mode. A text stream is created and passed on to the super class - * WriterAppender. - * - * If the parent directory of the specified file does not exists, - * it is created. - */ - void openFile(); - - /*! - * Removes the file \a rFile. If the operation is successful, true is - * returned. Otherwise an APPENDER_REMOVE_FILE_ERROR error is logged - * and false is returned. - */ - bool removeFile(QFile &rFile) const; - - /*! - * Renames the file \a rFile to \a rFileName. If the operation is - * successful, true is returned. Otherwise an - * APPENDER_RENAMING_FILE_ERROR error is logged and false is returned. - */ - bool renameFile(QFile &rFile, - const QString &rFileName) const; - - // JAVA: void setQWForFiles(Writer writer); - - private: - volatile bool mAppendFile; - volatile bool mBufferedIo; - QString mFileName; - QFile *mpFile; - QTextStream *mpTextStream; - }; - - - /************************************************************************** - * Operators, Helper - **************************************************************************/ - - - /************************************************************************** - * Inline - **************************************************************************/ - - inline bool FileAppender::appendFile() const - { // QMutexLocker locker(&mObjectGuard); // Read/Write of int is safe - return mAppendFile; } - - inline QString FileAppender::file() const - { QMutexLocker locker(&mObjectGuard); - return mFileName; } - - inline bool FileAppender::bufferedIo() const - { // QMutexLocker locker(&mObjectGuard); // Read/Write of int is safe - return mBufferedIo; } - - inline void FileAppender::setAppendFile(bool append) - { // QMutexLocker locker(&mObjectGuard); // Read/Write of int is safe - mAppendFile = append; } - - inline void FileAppender::setBufferedIo(bool buffered) - { // QMutexLocker locker(&mObjectGuard); // Read/Write of int is safe - mBufferedIo = buffered; } - - inline void FileAppender::setFile(const QString &rFileName) - { QMutexLocker locker(&mObjectGuard); - mFileName = rFileName; } - - -} // namespace Log4Qt - - -// Q_DECLARE_TYPEINFO(Log4Qt::FileAppender, Q_COMPLEX_TYPE); // Use default - - -#endif // LOG4QT_FILEAPPENDER_H diff --git a/src/log4qt/src/log4qt/helpers/classlogger.cpp b/src/log4qt/src/log4qt/helpers/classlogger.cpp deleted file mode 100644 index 50b6c7f..0000000 --- a/src/log4qt/src/log4qt/helpers/classlogger.cpp +++ /dev/null @@ -1,100 +0,0 @@ -/****************************************************************************** - * - * package: Log4Qt - * file: classlogger.cpp - * created: September 2007 - * author: Martin Heinrich - * - * - * changes: Sep 2008, Martin Heinrich: - * - Replaced usage of q_atomic_test_and_set_ptr with - * QAtomicPointer - * - * - * Copyright 2007 - 2008 Martin Heinrich - * - * 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. - * - ******************************************************************************/ - - - -/****************************************************************************** - * Dependencies - ******************************************************************************/ - - -#include "log4qt/helpers/classlogger.h" - -#include -#include "log4qt/logmanager.h" - - -namespace Log4Qt -{ - - - /************************************************************************** - * Declarations - **************************************************************************/ - - - - /************************************************************************** - * C helper functions - **************************************************************************/ - - - - /************************************************************************** - * Class implementation: ClassLogger - **************************************************************************/ - - - ClassLogger::ClassLogger() : - mpLogger(0) - { - } - - - Logger *ClassLogger::logger(const QObject *pObject) - { - Q_ASSERT_X(pObject, "ClassLogger::logger()", "pObject must not be null"); -#if QT_VERSION < QT_VERSION_CHECK(4, 4, 0) - if (!mpLogger) - q_atomic_test_and_set_ptr(&mpLogger, - 0, - LogManager::logger(QLatin1String(pObject->metaObject()->className()))); - return const_cast(mpLogger); -#elif QT_VERSION < QT_VERSION_CHECK(5, 0, 0) - if (!static_cast(mpLogger)) - mpLogger.testAndSetOrdered(0, - LogManager::logger(QLatin1String(pObject->metaObject()->className()))); - return const_cast(static_cast(mpLogger)); -#else - if (!static_cast(mpLogger.loadAcquire())) - mpLogger.testAndSetOrdered(0, - LogManager::logger(QLatin1String(pObject->metaObject()->className()))); - return const_cast(static_cast(mpLogger.loadAcquire())); -#endif - } - - - - /************************************************************************** - * Implementation: Operators, Helper - **************************************************************************/ - - - -} // namespace Log4Qt diff --git a/src/log4qt/src/log4qt/helpers/classlogger.h b/src/log4qt/src/log4qt/helpers/classlogger.h deleted file mode 100644 index 065a852..0000000 --- a/src/log4qt/src/log4qt/helpers/classlogger.h +++ /dev/null @@ -1,115 +0,0 @@ -/****************************************************************************** - * - * package: Log4Qt - * file: classlogger.h - * created: September 2007 - * author: Martin Heinrich - * - * - * changes: Sep 2008, Martin Heinrich: - * - Replaced usage of q_atomic_test_and_set_ptr with - * QAtomicPointer - * - * - * Copyright 2007 - 2008 Martin Heinrich - * - * 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. - * - ******************************************************************************/ - -#ifndef LOG4QT_CLASSLOGGER_H -#define LOG4QT_CLASSLOGGER_H - - -/****************************************************************************** - * Dependencies - ******************************************************************************/ - -#include -#if QT_VERSION >= QT_VERSION_CHECK(4, 4, 0) -# include -# ifndef Q_ATOMIC_POINTER_TEST_AND_SET_IS_ALWAYS_NATIVE -# warning "QAtomicPointer test and set is not native. The class Log4Qt::ClassLogger is not thread-safe." -# endif -#endif - - -/****************************************************************************** - * Declarations - ******************************************************************************/ - -namespace Log4Qt -{ - class Logger; - - /*! - * \brief The class ClassLogger provides logging for a QObject derived - * class. - * - * The class ClassLogger provides a logger for a specified QObject derived - * object. It is used by \ref LOG4QT_DECLARE_QCLASS_LOGGER to implement the - * member functions provided by the macro. - * - * \note All the functions declared in this class are thread-safe. - * - * \sa LOG4QT_DECLARE_QCLASS_LOGGER - */ - class ClassLogger - { - public: - /*! - * Creates a ClassLogger object. - */ - ClassLogger(); - // ~ClassLogger(); // Use compiler default - // ClassLogger(const ClassLogger &rOther); // Use compiler default - // ClassLogger &operator=(const ClassLogger &rOther); // Use compiler default - - /*! - * Returns a pointer to a Logger named after the class of the object - * \a pObject. - * - * On the first invocation the Logger is requested by a call to - * LogManager::logger(const char *pName). The pointer is stored to be - * returned on subsequent invocations. - * - * \sa LogManager::logger(const char *pName) - */ - Logger *logger(const QObject *pObject); - - private: -#if QT_VERSION < QT_VERSION_CHECK(4, 4, 0) - volatile Logger *mpLogger; -#else - mutable QAtomicPointer mpLogger; -#endif - }; - - - /****************************************************************************** - * Operators, Helper - ******************************************************************************/ - - - /************************************************************************** - * Inline - **************************************************************************/ - - -} // namespace Log4Qt - - -// Q_DECLARE_TYPEinfo(Log4Qt::ClassLogger, Q_COMPLEX_TYPE); // Use default - - -#endif // LOG4QT_CLASSLOGGER_H diff --git a/src/log4qt/src/log4qt/helpers/configuratorhelper.cpp b/src/log4qt/src/log4qt/helpers/configuratorhelper.cpp deleted file mode 100644 index 3b34f40..0000000 --- a/src/log4qt/src/log4qt/helpers/configuratorhelper.cpp +++ /dev/null @@ -1,136 +0,0 @@ -/****************************************************************************** - * - * package: Log4Qt - * file: configuratorhelper.cpp - * created: September 2007 - * author: Martin Heinrich - * - * - * Copyright 2007 Martin Heinrich - * - * 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. - * - ******************************************************************************/ - - - -/****************************************************************************** - * Dependencies - ******************************************************************************/ - - -#include "log4qt/helpers/configuratorhelper.h" - -#include -#include -#include "log4qt/helpers/initialisationhelper.h" - - - -namespace Log4Qt -{ - - - /************************************************************************** - * Declarations - **************************************************************************/ - - - - /************************************************************************** - * C helper functions - **************************************************************************/ - - - - /************************************************************************** - * Class implementation: ConfiguratorHelper - **************************************************************************/ - - - ConfiguratorHelper::ConfiguratorHelper() : - mObjectGuard(), - mConfigurationFile(), - mpConfigureFunc(0), - mpConfigurationFileWatch(0), - mConfigureError() - { - } - - - ConfiguratorHelper::~ConfiguratorHelper() - { - delete mpConfigurationFileWatch; - } - - - LOG4QT_IMPLEMENT_INSTANCE(ConfiguratorHelper) - - - void ConfiguratorHelper::doConfigurationFileChanged(const QString &rFileName) - { - QMutexLocker locker(&mObjectGuard); - - if (!mpConfigureFunc) - return; - mpConfigureFunc(rFileName); - // Shall we hold the lock while emitting the signal? - emit configurationFileChanged(rFileName, mConfigureError.count() > 0); - } - - - - void ConfiguratorHelper::doSetConfigurationFile(const QString &rFileName, - ConfigureFunc pConfigureFunc) - { - QMutexLocker locker(&mObjectGuard); - - mConfigurationFile.clear(); - mpConfigureFunc = 0; - delete mpConfigurationFileWatch; - if (rFileName.isEmpty()) - return; - - mConfigurationFile = rFileName; - mpConfigureFunc = pConfigureFunc; - mpConfigurationFileWatch = new QFileSystemWatcher(); - mpConfigurationFileWatch->addPath(rFileName); - connect(mpConfigurationFileWatch, - SIGNAL(fileChanged(const QString &)), - SLOT(configurationFileChanged(const QString &))); - } - - - - /************************************************************************** - * Implementation: Operators, Helper - **************************************************************************/ - - -#ifndef QT_NO_DEBUG_STREAM - QDebug operator<<(QDebug debug, - const ConfiguratorHelper &rConfiguratorHelper) - { - debug.nospace() << "ConfiguratorHelper(" - << "configurationfile:" << ConfiguratorHelper::configurationFile() - << "configurefunc:" << rConfiguratorHelper.mpConfigureFunc - << "filesystemwatcher:" << rConfiguratorHelper.mpConfigurationFileWatch - << ")"; - return debug.space(); - } -#endif // QT_NO_DEBUG_STREAM - - - -} // namespace Log4Qt - diff --git a/src/log4qt/src/log4qt/helpers/configuratorhelper.h b/src/log4qt/src/log4qt/helpers/configuratorhelper.h deleted file mode 100644 index 765f86a..0000000 --- a/src/log4qt/src/log4qt/helpers/configuratorhelper.h +++ /dev/null @@ -1,210 +0,0 @@ -/****************************************************************************** - * - * package: Log4Qt - * file: configuratorhelper.h - * created: September 2007 - * author: Martin Heinrich - * - * - * Copyright 2007 Martin Heinrich - * - * 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. - * - ******************************************************************************/ - -#ifndef LOG4QT_HELPERS_CONFIGURATORHELPER_H -#define LOG4QT_HELPERS_CONFIGURATORHELPER_H - - -/****************************************************************************** - * Dependencies - ******************************************************************************/ - -#include - -#include -#include -#include "log4qt/loggingevent.h" - - -/****************************************************************************** - * Declarations - ******************************************************************************/ - -class QFileSystemWatcher; - - -namespace Log4Qt -{ - - /*! - * \brief The class ConfiguratorHelper provides a confiuration file watch - * and last error for configurator classes. - * - * A configuration file can be set using setConfigurationFile(). The file - * is watched for changes. If a change occurs the configuration is reloaded - * and the ConfigurationFileChanged() signal is emitted. Error information - * for the last call to a configure function or the last configuration file - * change can be accessed using configureError(). - * - * \note All the functions declared in this class are thread-safe. - */ - class ConfiguratorHelper : public QObject - { - Q_OBJECT - - public: - /*! - * Prototype for a configure callback function. The function is called - * when then configuration file is changed and takes the - * configuration file as a parameter. - * - * \sa setConfigurationFile(), - * PropertyConfigurator::configure(const QString &) - */ - typedef bool (*ConfigureFunc)(const QString &rFileName); - - private: - ConfiguratorHelper(); - ConfiguratorHelper(const ConfiguratorHelper &rOther); // Not implemented - virtual ~ConfiguratorHelper(); - ConfiguratorHelper &operator=(const ConfiguratorHelper &rOther); // Not implemented - - public: - - /*! - * Returns the error information for the last configuration operation - * that took place. The configuration operation could be the result of - * a call to one of the configure methods or through a change - * to the configuration file. - * - * \sa setConfigureError(), PropertyConfigurator::configure(), - * setConfigurationFile() - */ - static QList configureError(); - - /*! - * Returns the current configuration file. - * - * \sa setConfigurationFile() - */ - static QString configurationFile(); - - /*! - * Returns the ConfiguratorHelper instance. - */ - static ConfiguratorHelper *instance(); - - /*! - * Sets the configuration error information for the last configuration - * operation. - * - * \sa configureError() - */ - static void setConfigureError(const QList &rConfigureError); - - /*! - * Sets the configuration file to \a rFileName. The file is watched for - * changes. On a file change the function \a pConfigureFunc will be called - * and the signal configurationFileChange() will be emitted. - * - * Setting the configuration file to an empty string stops the file watch. - * - * \sa configurationFile(), PropertyConfigurator::configureAndWatch(), - * configureError() - */ - static void setConfigurationFile(const QString &rFileName = QString(), - ConfigureFunc pConfigureFunc = 0); - - signals: - /*! - * The signal is emitted after a change to the file \a rFileName - * was processed. If an error occured during the configuration, the - * flag \a error will be true and error information is available - * over configureError(). - */ - void configurationFileChanged(const QString &rFileName, - bool error); - - private slots: - void doConfigurationFileChanged(const QString &rFileName); - - private: - void doSetConfigurationFile(const QString &rFileName, - ConfigureFunc pConfigureFunc); - - private: - mutable QMutex mObjectGuard; - QString mConfigurationFile; - ConfigureFunc mpConfigureFunc; - QFileSystemWatcher *mpConfigurationFileWatch; - QList mConfigureError; - -#ifndef QT_NO_DEBUG_STREAM - // Needs to be friend to access details - friend QDebug operator<<(QDebug debug, - const ConfiguratorHelper &rConfiguratorHelper); -#endif // QT_NO_DEBUG_STREAM - }; - - - /************************************************************************** - * Operators, Helper - **************************************************************************/ - -#ifndef QT_NO_DEBUG_STREAM - /*! - * \relates ConfiguratorHelper - * - * Writes all object member variables to the given debug stream \a rDebug and - * returns the stream. - * - * - * %ConfiguratorHelper(configurationfile: "" configurefunc: false - * filesystemwatcher: QObject(0x0) ) - * - * \sa QDebug, ConfiguratorHelper::logManager() - */ - QDebug operator<<(QDebug debug, - const ConfiguratorHelper &rConfiguratorHelper); -#endif // QT_NO_DEBUG_STREAM - - - - /************************************************************************** - * Inline - **************************************************************************/ - - inline QList ConfiguratorHelper::configureError() - { QMutexLocker locker(&instance()->mObjectGuard); - return instance()->mConfigureError; } - - inline QString ConfiguratorHelper::configurationFile() - { QMutexLocker locker(&instance()->mObjectGuard); - return instance()->mConfigurationFile; } - - inline void ConfiguratorHelper::setConfigureError(const QList &rConfigureError) - { QMutexLocker locker(&instance()->mObjectGuard); - instance()->mConfigureError = rConfigureError; } - - inline void ConfiguratorHelper::setConfigurationFile(const QString &rFileName, - ConfigureFunc pConfigureFunc) - { instance()->doSetConfigurationFile(rFileName, pConfigureFunc); } - -} // namespace Log4Qt - - -// Q_DECLARE_TYPEINFO(Log4Qt::ConfiguratorHelper, Q_COMPLEX_TYPE); // use default - - -#endif // LOG4QT_HELPERS_CONFIGURATORHELPER_H diff --git a/src/log4qt/src/log4qt/helpers/datetime.cpp b/src/log4qt/src/log4qt/helpers/datetime.cpp deleted file mode 100644 index 081dc10..0000000 --- a/src/log4qt/src/log4qt/helpers/datetime.cpp +++ /dev/null @@ -1,326 +0,0 @@ -/****************************************************************************** - * - * package: Log4Qt - * file: datetime.cpp - * created: September 2007 - * author: Martin Heinrich - * - * - * Copyright 2007 Martin Heinrich - * - * 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. - * - ******************************************************************************/ - - - -/****************************************************************************** - * Dependencies - ******************************************************************************/ - - -#include "log4qt/helpers/datetime.h" - -#include -#include "log4qt/helpers/initialisationhelper.h" - - - -namespace Log4Qt -{ - - - /************************************************************************** - *Declarations - **************************************************************************/ - - - - /************************************************************************** - * C helper functions - **************************************************************************/ - - - - /************************************************************************** - * Class implementation: DateTime - **************************************************************************/ - - - QString DateTime::toString(const QString &rFormat) const - { - QString format(rFormat); - - if (format.isEmpty()) - return QString(); - if (!isValid()) - return QString(); - if (format == QLatin1String("NONE")) - return QString(); - - if (format == QLatin1String("TIME_RELATIVE")) - return QString::number(toMilliSeconds() - InitialisationHelper::startTime()); - - if (format == QLatin1String("ISO8601")) - format = QLatin1String("yyyy-MM-dd hh:mm:ss.zzz"); - if (format == QLatin1String("TIME_ABSOLUTE")) - format = QLatin1String("HH:mm:ss.zzz"); - if (format == QLatin1String("DATE")) - format = QLatin1String("dd MMM YYYY HH:mm:ss.zzzz"); - - return formatDateTime(format); - } - - - QString DateTime::formatDateTime(const QString &rFormat) const - { - if (rFormat.isEmpty()) - return QString(); - if (!isValid()) - return QString(); - - const QLatin1Char null('0'); - const QLatin1Char quote('\''); - const QString tokens = QLatin1String("\'dMyhHmszAPapw"); - const bool am_pm = hasAMPM(rFormat); - - QString result; - QString token; - QChar expected = null; - - QChar c; - int i; - for (i = 0; i < rFormat.length(); i++) - { - c = rFormat.at(i); - - // Handle literal text - if (expected == quote) - { - if (c == quote) - { - Q_ASSERT_X(i > 0, "DateTime::toString()", "Found quote with status quote at i = 0"); - if (i > 0 && rFormat.at(i - 1) == quote) - // Second of two quotes - result += quote; - expected = null; - } - else - // Next literal character - result += c; - } - else if (c == expected) - { - // Extend token - token += c; - } - else - { - // Close last token - result += formatToken(token, am_pm); - token.clear(); - expected = null; - - // Test for valid character - if (tokens.indexOf(c) >= 0) - { - if (c == QLatin1Char('a')) - expected = QLatin1Char('p'); - else if (c == QLatin1Char('A')) - expected = QLatin1Char('P'); - else if (c.toLower() == QLatin1Char('p')) - expected = null; - else - expected = c; - if (c != quote) - token += c; - } else - result += c; - } - } - - result += formatToken(token, am_pm); - return result; - } - - - QString DateTime::formatToken(const QString &rToken, bool am_pm) const - { - if (rToken.isEmpty()) - return QString(); - - const QChar c = rToken.at(0); - QString result; - int used; - - // Qt data format strings - if (rToken.startsWith(QLatin1String("dddd"))) - { - result = QDate::longDayName(date().dayOfWeek()); - used = 4; - } - else if (rToken.startsWith(QLatin1String("ddd"))) - { - result = QDate::shortDayName(date().dayOfWeek()); - used = 3; - } - else if (rToken.startsWith(QLatin1String("dd"))) - { - result = QString::number(date().day()).rightJustified(2, QLatin1Char('0'), true); - used = 2; - } - else if (c == QLatin1Char('d')) - { - result = QString::number(date().day()); - used = 1; - } - else if (rToken.startsWith(QLatin1String("MMMM"))) - { - result = QDate::longMonthName(date().month()); - used = 4; - } - else if (rToken.startsWith(QLatin1String("MMM"))) - { - result = QDate::shortMonthName(date().month()); - used = 3; - } - else if (rToken.startsWith(QLatin1String("MM"))) - { - result = QString::number(date().month()).rightJustified(2, QLatin1Char('0'), true); - used = 2; - } - else if (c == QLatin1Char('M')) - { - result = QString::number(date().month()); - used = 1; - } - else if (rToken.startsWith(QLatin1String("yyyy"))) - { - result = QString::number(date().year()); - used = 4; - } - else if (rToken.startsWith(QLatin1String("yy"))) - { - result = QString::number(date().year() % 100).rightJustified(2, QLatin1Char('0'), true); - used = 2; - } - - // Qt time format strings - else if (rToken.startsWith(QLatin1String("hh")) || rToken.startsWith(QLatin1String("HH"))) - { - int hour = time().hour(); - if (am_pm && c == QLatin1Char('h') && hour > 12) - hour -= 12; - result = QString::number(hour).rightJustified(2, QLatin1Char('0'), true); - used = 2; - } - else if (c == QLatin1Char('h') || c == QLatin1Char('H')) - { - int hour = time().hour(); - if (am_pm && c == QLatin1Char('h') && hour > 12) - hour -= 12; - result = QString::number(hour); - used = 2; - } - else if (rToken.startsWith(QLatin1String("mm"))) - { - result = QString::number(time().minute()).rightJustified(2, QLatin1Char('0'), true); - used = 2; - } - else if (c == (QLatin1Char('m'))) - { - result = QString::number(time().minute()); - used = 1; - } - else if (rToken.startsWith(QLatin1String("ss"))) - { - result = QString::number(time().second()).rightJustified(2, QLatin1Char('0'), true); - used = 2; - } - else if (c == QLatin1Char('s')) - { - result = QString::number(time().second()); - used = 1; - } - else if (rToken.startsWith(QLatin1String("zzz"))) - { - result = QString::number(time().msec()).rightJustified(3, QLatin1Char('0'), true); - used = 3; - } - else if (c == QLatin1Char('z')) - { - result = QString::number(time().msec()); - used = 1; - } - else if (c.toLower() == QLatin1Char('a')) - { - bool is_lower = c == QLatin1Char('a'); - if (time().hour() < 12) - result = QLatin1String("AM"); - else - result = QLatin1String("PM"); - if (is_lower) - result = result.toLower(); - if (rToken.size() > 1 && - ((is_lower && rToken.at(1) == QLatin1Char('p')) || - (!is_lower && rToken.at(1) == QLatin1Char('P'))) - ) - used = 2; - else - used = 1; - } - - // Extension for week number - else if (rToken.startsWith(QLatin1String("ww"))) - { - result = QString::number(date().weekNumber()).rightJustified(2, QLatin1Char('0'), true); - used = 2; - } - else if (c == QLatin1Char('w')) - { - result = QString::number(date().weekNumber()); - used = 1; - } - - if (used) - return result + formatToken(rToken.mid(used), am_pm); - else - return result; - } - - - bool DateTime::hasAMPM(const QString &rToken) - { - bool in_literal = false; - QChar c; - int i; - for (i = 0; i < rToken.length(); i++) - { - c = rToken.at(i); - if (c == QLatin1Char('\'')) - in_literal = !in_literal; - else if (!in_literal && c.toLower() == QLatin1Char('a')) - return true; - } - return false; - } - - - - /************************************************************************** - * Implementation: Operators, Helper - **************************************************************************/ - - - -} // namespace Log4Qt diff --git a/src/log4qt/src/log4qt/helpers/datetime.h b/src/log4qt/src/log4qt/helpers/datetime.h deleted file mode 100644 index 0b89735..0000000 --- a/src/log4qt/src/log4qt/helpers/datetime.h +++ /dev/null @@ -1,212 +0,0 @@ -/****************************************************************************** - * - * package: Log4Qt - * file: datetime.h - * created: September 2007 - * author: Martin Heinrich - * - * - * changes: Sep 2008, Martin Heinrich: - * - Resolved compilation problem with Microsoft Visual Studio 2005 - * - * - * Copyright 2007 - 2008 Martin Heinrich - * - * 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. - * - ******************************************************************************/ - -#ifndef LOG4QT_HELPERS_DATETIME_H -#define LOG4QT_HELPERS_DATETIME_H - - -/****************************************************************************** - * Dependencies - ******************************************************************************/ - -#include - - -/****************************************************************************** - * Declarations - ******************************************************************************/ - - -namespace Log4Qt -{ - - /*! - * \brief The class DateTime provides extended functionality for QDateTime. - * - * The class DateTime implements additional formatting options for - * toString() and provides conversion functions from and to milliseconds. - */ - class DateTime : public QDateTime - { - public: - /*! - * Constructs a null date time. - * - * \sa QDateTime::QDateTime() - */ - DateTime(); - - // DateTime(const DateTime &rOther); // Use compiler default - - /*! - * Constructs a copy of another QDateTime. - * - * \sa QDateTime::QDateTime(const QDateTime &rOther) - */ - DateTime(const QDateTime &rOther); - - /*! - * Constructs a datetime with the given \a rDate and \a rTime, using - * the time specification defined by \a timeSpec. - * - * \sa QDateTime::QDateTime(const QDate &rDate, const QTime &rTime, - * Qt::TimeSpec timeSpec = Qt::LocalTime) - */ - DateTime(const QDate &rDate, - const QTime &rTime, - Qt::TimeSpec timeSpec = Qt::LocalTime); - - // virtual ~DateTime(); // Use compiler default - - /*! - * Assigns \a rOther to this DateTime and returns a reference to it. - */ - DateTime &operator=(const DateTime &rOther); - - /*! - * Returns the datetime as the number of milliseconds that have passed - * since 1970-01-01T00:00:00,000, Coordinated Universal Time (Qt::UTC). - * - * \sa QDateTime::toTime_t() - */ - qint64 toMilliSeconds() const; - - /*! - * Returns the datetime as a string. The \a rFormat parameter - * determines the format of the result string. - * - * In addition to the expressions of QDateTime::toString(const QString - * &rFormat) the following expression can be used. - * - * - * - * - * - * - * - * - * - * - * - * - *
Expression Output
w the week of the year as number without a leading zero (1 to 53)
ww the week of the year as number with a leading zero (01 to 53)
- * - * Alternatively the \a rFormat parameter can specify one of the - * following strings. - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - *
String Format
TIME_ABSOLUTE uses the format HH:mm:ss.zzz
DATE uses the format dd MMM YYYY HH:mm:ss.zzzz
ISO8601 uses the format yyyy-MM-dd hh:mm:ss.zzz
NONE uses an empty string as format
TIME_RELATIVE returns the milliseconds since start of the program
- * - * \sa QDateTime::toString(const QString &rFormat) - */ - QString toString(const QString &rFormat) const; - - /*! - * Returns the current datetime, as reported by the system clock, in - * the local time zone. - * - * \sa QDateTime::currentDateTime() - */ - static DateTime currentDateTime(); - - /*! - * Returns a datetime whose date and time are the number of - * milliseconds that have passed since 1970-01-01T00:00:00, - * Coordinated Universal Time (Qt::UTC). - * - * \sa QDateTime::fromTime_t(uint seconds) - */ - static DateTime fromMilliSeconds(qint64 milliSeconds); - - private: - QString formatDateTime(const QString &rFormat) const; - QString formatToken(const QString &rToken, bool am_pm) const; - static bool hasAMPM(const QString &rFormat); - }; - - - /************************************************************************** - * Operators, Helper - **************************************************************************/ - - - /************************************************************************** - * Inline - **************************************************************************/ - - inline DateTime::DateTime() : QDateTime() - {} - - inline DateTime::DateTime(const QDateTime &rOther) : QDateTime(rOther) - {} - - inline DateTime::DateTime(const QDate &rDate, - const QTime &rTime, - Qt::TimeSpec timeSpec) : - QDateTime(rDate, rTime, timeSpec) - {} - - inline DateTime &DateTime::operator=(const DateTime &rOther) - { QDateTime::operator=(rOther); return *this; } - - inline qint64 DateTime::toMilliSeconds() const - { return (qint64)1000 * toTime_t() + time().msec(); } - - inline DateTime DateTime::currentDateTime() - { return DateTime(QDateTime::currentDateTime()); } - - inline DateTime DateTime::fromMilliSeconds(qint64 milliSeconds) - { return DateTime(QDateTime::fromTime_t(milliSeconds / 1000).addMSecs(milliSeconds % 1000)); } - - -} // namespace Log4Qt - - -Q_DECLARE_TYPEINFO(Log4Qt::DateTime, Q_MOVABLE_TYPE); - - -#endif // LOG4QT_HELPERS_DATETIME_H diff --git a/src/log4qt/src/log4qt/helpers/factory.cpp b/src/log4qt/src/log4qt/helpers/factory.cpp deleted file mode 100644 index bf2f449..0000000 --- a/src/log4qt/src/log4qt/helpers/factory.cpp +++ /dev/null @@ -1,459 +0,0 @@ -/****************************************************************************** - * - * package: Log4Qt - * file: factory.cpp - * created: September 2007 - * author: Martin Heinrich - * - * - * Copyright 2007 Martin Heinrich - * - * 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. - * - ******************************************************************************/ - - - -/****************************************************************************** - * Dependencies - ******************************************************************************/ - - -#include "log4qt/helpers/factory.h" - -#include -#include -#include -#include "log4qt/consoleappender.h" -#include "log4qt/dailyrollingfileappender.h" -#include "log4qt/fileappender.h" -#include "log4qt/helpers/logerror.h" -#include "log4qt/helpers/initialisationhelper.h" -#include "log4qt/helpers/optionconverter.h" -#include "log4qt/patternlayout.h" -#include "log4qt/rollingfileappender.h" -#include "log4qt/simplelayout.h" -#include "log4qt/ttcclayout.h" -#include "log4qt/varia/debugappender.h" -#include "log4qt/varia/denyallfilter.h" -#include "log4qt/varia/levelmatchfilter.h" -#include "log4qt/varia/levelrangefilter.h" -#include "log4qt/varia/listappender.h" -#include "log4qt/varia/nullappender.h" -#include "log4qt/varia/stringmatchfilter.h" - - - -namespace Log4Qt -{ - - - /************************************************************************** - * Declarations - **************************************************************************/ - - - - /************************************************************************** - * C helper functions - **************************************************************************/ - - - LOG4QT_DECLARE_STATIC_LOGGER(logger, Log4Qt::Factory) - - - // Appenders - - Appender *console_file_appender() - { return new ConsoleAppender; } - - Appender *create_daily_rolling_file_appender() - { return new DailyRollingFileAppender; } - - Appender *create_debug_appender() - { return new DebugAppender; } - - Appender *create_file_appender() - { return new FileAppender; } - - Appender *create_list_appender() - { return new ListAppender; } - - Appender *create_null_appender() - { return new NullAppender; } - - Appender *create_rolling_file_appender() - { return new RollingFileAppender; } - - - // Filters - - Filter *create_deny_all_filter() - { return new DenyAllFilter; } - - Filter *create_level_match_filter() - { return new LevelMatchFilter; } - - Filter *create_level_range_filter() - { return new LevelRangeFilter; } - - Filter *create_string_match_filter() - { return new StringMatchFilter; } - - - // Layouts - - Layout *create_pattern_layout() - { return new PatternLayout; } - - Layout *create_simple_layout() - { return new SimpleLayout; } - - Layout *create_ttcc_layout() - { return new TTCCLayout; } - - - - /************************************************************************** - * Class implementation: Factory - **************************************************************************/ - - - Factory::Factory() : - mObjectGuard(), - mAppenderRegistry(), - mFilterRegistry(), - mLayoutRegistry() - { - registerDefaultAppenders(); - registerDefaultFilters(); - registerDefaultLayouts(); - } - - - LOG4QT_IMPLEMENT_INSTANCE(Factory) - - - Appender *Factory::doCreateAppender(const QString &rAppenderClassName) - { - QMutexLocker locker(&mObjectGuard); - - if (!mAppenderRegistry.contains(rAppenderClassName)) - { - logger()->warn("Request for the creation of Appender with class '%1', which is not registered", rAppenderClassName); - return 0; - } - return mAppenderRegistry.value(rAppenderClassName)(); - } - - - Filter *Factory::doCreateFilter(const QString &rFilterClassName) - { - QMutexLocker locker(&mObjectGuard); - - if (!mFilterRegistry.contains(rFilterClassName)) - { - logger()->warn("Request for the creation of Filter with class '%1', which is not registered", rFilterClassName); - return 0; - } - return mFilterRegistry.value(rFilterClassName)(); - } - - - Layout *Factory::doCreateLayout(const QString &rLayoutClassName) - { - QMutexLocker locker(&mObjectGuard); - - if (!mLayoutRegistry.contains(rLayoutClassName)) - { - logger()->warn("Request for the creation of Layout with class '%1', which is not registered", rLayoutClassName); - return 0; - } - return mLayoutRegistry.value(rLayoutClassName)(); - } - - - void Factory::doRegisterAppender(const QString &rAppenderClassName, - AppenderFactoryFunc pAppenderFactoryFunc) - { - QMutexLocker locker(&mObjectGuard); - - if(rAppenderClassName.isEmpty()) - { - logger()->warn("Registering Appender factory function with empty class name"); - return; - } - mAppenderRegistry.insert(rAppenderClassName, pAppenderFactoryFunc); - } - - - void Factory::doRegisterFilter(const QString &rFilterClassName, - FilterFactoryFunc pFilterFactoryFunc) - { - QMutexLocker locker(&mObjectGuard); - - if(rFilterClassName.isEmpty()) - { - logger()->warn("Registering Filter factory function with empty class name"); - return; - } - mFilterRegistry.insert(rFilterClassName, pFilterFactoryFunc); - } - - - void Factory::doRegisterLayout(const QString &rLayoutClassName, - LayoutFactoryFunc pLayoutFactoryFunc) - { - QMutexLocker locker(&mObjectGuard); - - if(rLayoutClassName.isEmpty()) - { - logger()->warn("Registering Layout factory function with empty class name"); - return; - } - mLayoutRegistry.insert(rLayoutClassName, pLayoutFactoryFunc); - } - - - void Factory::doSetObjectProperty(QObject *pObject, - const QString &rProperty, - const QString &rValue) - { - // - Validate property - // - Get correct property name from meta object - // - Find specific property setter - // - If no specfifc propery setter can be found, - // find general property setter - // - Call property setter - - QMetaProperty meta_property; - if (!validateObjectProperty(meta_property, rProperty, pObject)) - return; - - QString property = QLatin1String(meta_property.name()); - QString type = QLatin1String(meta_property.typeName()); - logger()->debug("Setting property '%1' on object of class '%2' to value '%3'", - property, - QLatin1String(pObject->metaObject()->className()), - rValue); - - QVariant value; - bool ok = true; - if (type == QLatin1String("bool")) - value = OptionConverter::toBoolean(rValue, &ok); - else if (type == QLatin1String("int")) - value = OptionConverter::toInt(rValue, &ok); - else if (type == QLatin1String("qint64") || type == QLatin1String("qlonglong")) - value = OptionConverter::toQInt64(rValue, &ok); - else if (type == QLatin1String("Log4Qt::Level")) - value = QVariant::fromValue(OptionConverter::toLevel(rValue, &ok)); - else if (type == QLatin1String("QString")) - value = rValue; - else - { - LogError e = LOG4QT_ERROR(QT_TR_NOOP("Cannot convert to type '%1' for property '%2' on object of class '%3'"), - CONFIGURATOR_UNKNOWN_TYPE_ERROR, - "Log4Qt::Factory"); - e << type - << property - << QString::fromLatin1(pObject->metaObject()->className()); - logger()->error(e); - return; - } - if (!ok) - return; - - // Everything is checked and the type is the one of the property. - // Write should never return false - if (!meta_property.write(pObject, value)) - logger()->warn("Unxpected error result from QMetaProperty.write()"); - } - - - void Factory::doUnregisterAppender(const QString &rAppenderClassName) - { - QMutexLocker locker(&mObjectGuard); - - if (!mAppenderRegistry.contains(rAppenderClassName)) - { - logger()->warn("Request to unregister not registered Appender factory function for class '%1'", rAppenderClassName); - return; - } - mAppenderRegistry.remove(rAppenderClassName); - } - - - void Factory::doUnregisterFilter(const QString &rFilterClassName) - { - QMutexLocker locker(&mObjectGuard); - - if (!mFilterRegistry.contains(rFilterClassName)) - { - logger()->warn("Request to unregister not registered Filter factory function for class '%1'", rFilterClassName); - return; - } - mFilterRegistry.remove(rFilterClassName); - } - - - void Factory::doUnregisterLayout(const QString &rLayoutClassName) - { - QMutexLocker locker(&mObjectGuard); - - if (!mLayoutRegistry.contains(rLayoutClassName)) - { - logger()->warn("Request to unregister not registered Layout factory function for class '%1'", rLayoutClassName); - return; - } - mLayoutRegistry.remove(rLayoutClassName); - } - - - void Factory::registerDefaultAppenders() - { - mAppenderRegistry.insert(QLatin1String("org.apache.log4j.ConsoleAppender"), console_file_appender); - mAppenderRegistry.insert(QLatin1String("Log4Qt::ConsoleAppender"), console_file_appender); - mAppenderRegistry.insert(QLatin1String("org.apache.log4j.DailyRollingFileAppender"), create_daily_rolling_file_appender); - mAppenderRegistry.insert(QLatin1String("Log4Qt::DailyRollingFileAppender"), create_daily_rolling_file_appender); - mAppenderRegistry.insert(QLatin1String("org.apache.log4j.varia.DebugAppender"), create_debug_appender); - mAppenderRegistry.insert(QLatin1String("Log4Qt::DebugAppender"), create_debug_appender); - mAppenderRegistry.insert(QLatin1String("org.apache.log4j.FileAppender"), create_file_appender); - mAppenderRegistry.insert(QLatin1String("Log4Qt::FileAppender"), create_file_appender); - mAppenderRegistry.insert(QLatin1String("org.apache.log4j.varia.ListAppender"), create_list_appender); - mAppenderRegistry.insert(QLatin1String("Log4Qt::ListAppender"), create_list_appender); - mAppenderRegistry.insert(QLatin1String("org.apache.log4j.varia.NullAppender"), create_null_appender); - mAppenderRegistry.insert(QLatin1String("Log4Qt::NullAppender"), create_null_appender); - mAppenderRegistry.insert(QLatin1String("org.apache.log4j.RollingFileAppender"), create_rolling_file_appender); - mAppenderRegistry.insert(QLatin1String("Log4Qt::RollingFileAppender"), create_rolling_file_appender); - } - - - void Factory::registerDefaultFilters() - { - mFilterRegistry.insert(QLatin1String("org.apache.log4j.varia.DenyAllFilter"), create_deny_all_filter); - mFilterRegistry.insert(QLatin1String("Log4Qt::DenyAllFilter"), create_deny_all_filter); - mFilterRegistry.insert(QLatin1String("org.apache.log4j.varia.LevelMatchFilter"), create_level_match_filter); - mFilterRegistry.insert(QLatin1String("Log4Qt::LevelMatchFilter"), create_level_match_filter); - mFilterRegistry.insert(QLatin1String("org.apache.log4j.varia.LevelRangeFilter"), create_level_range_filter); - mFilterRegistry.insert(QLatin1String("Log4Qt::LevelRangeFilter"), create_level_range_filter); - mFilterRegistry.insert(QLatin1String("org.apache.log4j.varia.StringMatchFilter"), create_string_match_filter); - mFilterRegistry.insert(QLatin1String("Log4Qt::StringMatchFilter"), create_string_match_filter); - } - - - void Factory::registerDefaultLayouts() - { - mLayoutRegistry.insert(QLatin1String("org.apache.log4j.PatternLayout"), create_pattern_layout); - mLayoutRegistry.insert(QLatin1String("Log4Qt::PatternLayout"), create_pattern_layout); - mLayoutRegistry.insert(QLatin1String("org.apache.log4j.SimpleLayout"), create_simple_layout); - mLayoutRegistry.insert(QLatin1String("Log4Qt::SimpleLayout"), create_simple_layout); - mLayoutRegistry.insert(QLatin1String("org.apache.log4j.TTCCLayout"), create_ttcc_layout); - mLayoutRegistry.insert(QLatin1String("Log4Qt::TTCCLayout"), create_ttcc_layout); - } - - - bool Factory::validateObjectProperty(QMetaProperty &rMetaProperty, - const QString &rProperty, - QObject *pObject) - { - // Validate: - // - No null object pointer - // - No empty property name - // - Property exists on the object (QT or Java name) - // - Property is readable - // - Property is writable - - const char *p_context = "Log4Qt::Factory"; - LogError e = LOG4QT_ERROR(QT_TR_NOOP("Unable to set property value on object"), - CONFIGURATOR_PROPERTY_ERROR, - p_context); - - if (!pObject) - { - LogError ce = LOG4QT_ERROR(QT_TR_NOOP("Invalid null object pointer"), - 0, - p_context); - e.addCausingError(ce); - logger()->error(e); - return false; - } - if (rProperty.isEmpty()) - { - LogError ce = LOG4QT_ERROR(QT_TR_NOOP("Invalid empty property name"), - 0, - p_context); - e.addCausingError(ce); - logger()->error(e); - return false; - } - const QMetaObject *p_meta_object = pObject->metaObject(); - QString property = rProperty; - int i = p_meta_object->indexOfProperty(property.toLatin1()); - if (i < 0) - { - // Try name with lower case first character. Java properties names - // start upper case - property[0] = property[0].toLower(); - i = p_meta_object->indexOfProperty(property.toLatin1()); - if (i < 0) - { - LogError ce = LOG4QT_ERROR(QT_TR_NOOP("Property '%1' does not exist in class '%2'"), - 0, - p_context); - ce << property - << QString::fromLatin1(pObject->metaObject()->className()); - e.addCausingError(ce); - logger()->error(e); - return false; - } - } - rMetaProperty = p_meta_object->property(i); - if (!rMetaProperty.isWritable()) - { - LogError ce = LOG4QT_ERROR(QT_TR_NOOP("Property '%1' is not writable in class '%2'"), - 0, - p_context); - ce << property - << QString::fromLatin1(pObject->metaObject()->className()); - e.addCausingError(ce); - logger()->error(e); - return false; - } - - return true; - } - - - - /************************************************************************** - * Implementation: Operators, Helper - **************************************************************************/ - - -#ifndef QT_NO_DEBUG_STREAM - QDebug operator<<(QDebug debug, - const Factory &rFactory) - { - debug.nospace() << "Factory(" - << "appenderfactories:" << rFactory.registeredAppenders() - << "filterfactories:" << rFactory.registeredFilters() - << "layoutfactories:" << rFactory.registeredLayouts() - << ")"; - return debug.space(); - } -#endif // QT_NO_DEBUG_STREAM - - - -} // namespace Log4Qt - diff --git a/src/log4qt/src/log4qt/helpers/factory.h b/src/log4qt/src/log4qt/helpers/factory.h deleted file mode 100644 index d654928..0000000 --- a/src/log4qt/src/log4qt/helpers/factory.h +++ /dev/null @@ -1,492 +0,0 @@ -/****************************************************************************** - * - * package: Log4Qt - * file: factory.h - * created: September 2007 - * author: Martin Heinrich - * - * - * Copyright 2007 Martin Heinrich - * - * 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. - * - ******************************************************************************/ - -#ifndef LOG4QT_HELPERS_FACTORY_H -#define LOG4QT_HELPERS_FACTORY_H - - -/****************************************************************************** - * Dependencies - ******************************************************************************/ - -#include -#include -#include - -QT_BEGIN_NAMESPACE -class QMetaProperty; -class QObject; -QT_END_NAMESPACE - -/****************************************************************************** - * Declarations - ******************************************************************************/ - -namespace Log4Qt -{ - - class Appender; - class Filter; - class Layout; - - /*! - * \brief The class Factory provides factories for Appender, Filter and - * Layout objects. - * - * The functions createAppender(), createFilter() and createLayout() - * allow to create objects by specifying their class names. By default - * all classes of the package are recognised with their Log4j and Log4Qt - * classanmes. For example an object of the class FileAppender can be - * craeted using "org.apache.log4j.FileAppender" or "Log4Qt::FileAppender". - * Additional classes can be registered using registerAppender(), - * registerFilter() and registerLayout(). - * - * An QObject property can be set from a string value with - * setObjectProperty(). The function handles the required error checking - * and type conversion. - * - * \note All the functions declared in this class are thread-safe. - * - * \sa PropertyConfigurator - */ - class Factory - { - public: - /*! - * Prototype for an Appender factory function. The function creates - * an Appender object on the heap and returns a pointer to it. - * - * \sa registerAppender(), createAppender() - */ - typedef Appender *(*AppenderFactoryFunc)(); - - /*! - * Prototype for a Filter factory function. The function creates - * a Filter object on the heap and returns a pointer to it. - * - * \sa registerFilter(), createFilter() - */ - typedef Filter *(*FilterFactoryFunc)(); - - /*! - * Prototype for a Layout factory function. The function creates - * a Layout object on the heap and returns a pointer to it. - * - * \sa registerLayout(), createLayout() - */ - typedef Layout *(*LayoutFactoryFunc)(); - - private: - Factory(); - Q_DISABLE_COPY(Factory) - - public: - /*! - * Creates an object for the class \a rAppenderClassName on the heap - * and returns a pointer to it. If the class has no registered factory - * function a null pointer is returned. - * - * \sa registerAppender(), unregisterAppender(), registeredAppenders() - */ - static Appender *createAppender(const QString &rAppenderClassName); - - /*! - * This is an overloaded member function, provided for convenience. - */ - static Appender *createAppender(const char *pAppenderClassName); - - /*! - * Creates an object for the class \a rFilterClassName on the heap - * and returns a pointer to it. If the class has no registered factory - * function a null pointer is returned. - * - * \sa registerFilter(), unregisterFilter(), registeredFilters() - */ - static Filter *createFilter(const QString &rFilterClassName); - - /*! - * This is an overloaded member function, provided for convenience. - */ - static Filter *createFilter(const char *pFilterClassName); - - /*! - * Creates an object for the class \a rLayoutClassName on the heap - * and returns a pointer to it. If the class has no registered factory - * function a null pointer is returned. - * - * \sa registerLayout(), unregisterLayout(), registeredLayouts() - */ - static Layout *createLayout(const QString &rLayoutClassName); - - /*! - * This is an overloaded member function, provided for convenience. - */ - static Layout *createLayout(const char *pLayoutClassName); - - /*! - * Returns the Factory instance. - */ - static Factory *instance(); - - /*! - * Registers the Appender factory function \a pAppenderFactoryFunc - * for the class \a rAppenderClassName. If a registered factory - * function exists for the class, it is replaced with - * \a pAppenderFactoryFunc. - * - * \sa unregisterAppender(), registeredAppenders(), createAppender() - */ - static void registerAppender(const QString &rAppenderClassName, - AppenderFactoryFunc pAppenderFactoryFunc); - - /*! - * This is an overloaded member function, provided for convenience. - */ - static void registerAppender(const char *pAppenderClassName, - AppenderFactoryFunc pAppenderFactoryFunc); - - /*! - * Registers the Filter factory function \a pFilterFactoryFunc - * for the class \a rFilterClassName. If a registered factory - * function exists for the class, it is replaced with - * \a pFilterFactoryFunc. - * - * \sa unregisterFilter(), registeredFilters(), createFilter() - */ - static void registerFilter(const QString &rFilterClassName, - FilterFactoryFunc pFilterFactoryFunc); - - /*! - * This is an overloaded member function, provided for convenience. - */ - static void registerFilter(const char *pFilterClassName, - FilterFactoryFunc pFilterFactoryFunc); - - /*! - * Registers the Layout factory function \a pLayoutFactoryFunc - * for the class \a rLayoutClassName. If a registered factory - * function exists for the class, it is replaced with - * \a pLayoutFactoryFunc. - * - * \sa unregisterLayout(), registeredLayout(), createLayout() - */ - static void registerLayout(const QString &rLayoutClassName, - LayoutFactoryFunc pLayoutFactoryFunc); - - /*! - * This is an overloaded member function, provided for convenience. - */ - static void registerLayout(const char *pLayoutClassName, - LayoutFactoryFunc pLayoutFactoryFunc); - - /*! - * Returns a list of the class names for registered Appender factory - * functions. - * - * \sa registerAppender(), unregisterAppender() - */ - static QStringList registeredAppenders(); - - /*! - * Returns a list of the class names for registered Filter factory - * functions. - * - * \sa registerFilter(), unregisterFilter() - */ - static QStringList registeredFilters(); - - /*! - * Returns a list of the class names for registered Layout factory - * functions. - * - * \sa registerLayout(), unregisterLayout() - */ - static QStringList registeredLayouts(); - - /*! - * Sets the property \a rProperty of the object \a pObject to the - * value \a rValue. The function will test that the property - * \a rProperty is writeable and of a type the function can convert to. - * The types bool, int, Level and QString are supported. - * - * \sa OptionConverter - */ - static void setObjectProperty(QObject *pObject, - const QString &rProperty, - const QString &rValue); - - /*! - * This is an overloaded member function, provided for convenience. - */ - static void setObjectProperty(QObject *pObject, - const char *pProperty, - const QString &rValue); - - /*! - * Unregisters the Appender factory function for the class - * \a rAppenderClassName. - * - * \sa registerAppender(), registeredAppenders() - */ - static void unregisterAppender(const QString &rAppenderClassName); - - /*! - * This is an overloaded member function, provided for convenience. - */ - static void unregisterAppender(const char *pAppenderClassName); - - /*! - * Unregisters the Filter factory function for the class - * \a rFilterClassName. - * - * \sa registerFilter(), registeredFilters() - */ - static void unregisterFilter(const QString &rFilterClassName); - - /*! - * This is an overloaded member function, provided for convenience. - */ - static void unregisterFilter(const char *pFilterClassName); - - /*! - * Unregisters the Layout factory function for the class - * \a rLayoutClassName. - * - * \sa registerLayout(), registeredLayouts() - */ - static void unregisterLayout(const QString &rLayoutClassName); - - /*! - * This is an overloaded member function, provided for convenience. - */ - static void unregisterLayout(const char *pLayoutClassName); - - private: - Appender *doCreateAppender(const QString &rAppenderClassName); - Filter *doCreateFilter(const QString &rFilterClassName); - Layout *doCreateLayout(const QString &rLayoutClassName); - void doRegisterAppender(const QString &rAppenderClassName, - AppenderFactoryFunc pAppenderFactoryFunc); - void doRegisterFilter(const QString &rFilterClassName, - FilterFactoryFunc pFilterFactoryFunc); - void doRegisterLayout(const QString &rLayoutClassName, - LayoutFactoryFunc pLayoutFactoryFunc); - void doSetObjectProperty(QObject *pObject, - const QString &rProperty, - const QString &rValue); - void doUnregisterAppender(const QString &rAppenderClassName); - void doUnregisterFilter(const QString &rFilterClassName); - void doUnregisterLayout(const QString &rLayoutClassName); - void registerDefaultAppenders(); - void registerDefaultFilters(); - void registerDefaultLayouts(); - bool validateObjectProperty(QMetaProperty &rMetaProperty, - const QString &rProperty, - QObject *pObject); - - private: - mutable QMutex mObjectGuard; - QHash mAppenderRegistry; - QHash mFilterRegistry; - QHash mLayoutRegistry; - }; - - - /************************************************************************** - * Operators, Helper - **************************************************************************/ - -#ifndef QT_NO_DEBUG_STREAM - /*! - * \relates Factory - * - * Writes all object member variables to the given debug stream \a rDebug and - * returns the stream. - * - * - * %Factory(appenderfactories:("Log4Qt::DebugAppender", "Log4Qt::NullAppender", - * "Log4Qt::ConsoleAppender", "org.apache.log4j.varia.DebugAppender", - * "org.apache.log4j.FileAppender", "org.apache.log4j.RollingFileAppender", - * "org.apache.log4j.DailyRollingFileAppender", - * "org.apache.log4j.varia.ListAppender", - * "org.apache.log4j.varia.NullAppender", - * "Log4Qt::FileAppender", "org.apache.log4j.ConsoleAppender", - * "Log4Qt::DailyRollingFileAppender", "Log4Qt::ListAppender", - * "Log4Qt::RollingFileAppender") filterfactories: - * ("Log4Qt::DenyAllFilter", "Log4Qt::StringMatchFilter", - * "Log4Qt::LevelRangeFilter", "org.apache.log4j.varia.DenyAllFilter", - * "org.apache.log4j.varia.LevelRangeFilter", - * "org.apache.log4j.varia.StringMatchFilter", "Log4Qt::LevelMatchFilter", - * "org.apache.log4j.varia.LevelMatchFilter") layoutfactories: - * ("org.apache.log4j.SimpleLayout", "Log4Qt::PatternLayout", - * "Log4Qt::SimpleLayout", "org.apache.log4j.TTCCLayout", - * "Log4Qt::TTCCLayout", "org.apache.log4j.PatternLayout") ) - * - * \sa QDebug, Factory::logManager() - */ - QDebug operator<<(QDebug debug, - const Factory &rFactory); -#endif // QT_NO_DEBUG_STREAM - - - - /************************************************************************** - * Inline - **************************************************************************/ - - inline Appender *Factory::createAppender(const QString &rAppenderClassName) - { - return instance()->doCreateAppender(rAppenderClassName); - } - - inline Appender *Factory::createAppender(const char *pAppenderClassName) - { - return instance()->doCreateAppender(QLatin1String(pAppenderClassName)); - } - - inline Filter *Factory::createFilter(const QString &rFilterClassName) - { - return instance()->doCreateFilter(rFilterClassName); - } - - inline Filter *Factory::createFilter(const char *pFilterClassName) - { - return instance()->doCreateFilter(QLatin1String(pFilterClassName)); - } - - inline Layout *Factory::createLayout(const QString &rLayoutClassName) - { - return instance()->doCreateLayout(rLayoutClassName); - } - - inline Layout *Factory::createLayout(const char *pLayoutClassName) - { - return instance()->doCreateLayout(QLatin1String(pLayoutClassName)); - } - - inline void Factory::registerAppender(const QString &rAppenderClassName, - AppenderFactoryFunc pAppenderFactoryFunc) - { - instance()->doRegisterAppender(rAppenderClassName, pAppenderFactoryFunc); - } - - inline void Factory::registerAppender(const char *pAppenderClassName, - AppenderFactoryFunc pAppenderFactoryFunc) - { - instance()->doRegisterAppender(QLatin1String(pAppenderClassName), pAppenderFactoryFunc); - } - - inline void Factory::registerFilter(const QString &rFilterClassName, - FilterFactoryFunc pFilterFactoryFunc) - { - instance()->doRegisterFilter(rFilterClassName, pFilterFactoryFunc); - } - - inline void Factory::registerFilter(const char *pFilterClassName, - FilterFactoryFunc pFilterFactoryFunc) - { - instance()->doRegisterFilter(QLatin1String(pFilterClassName), pFilterFactoryFunc); - } - - inline void Factory::registerLayout(const QString &rLayoutClassName, - LayoutFactoryFunc pLayoutFactoryFunc) - { - instance()->doRegisterLayout(rLayoutClassName, pLayoutFactoryFunc); - } - - inline void Factory::registerLayout(const char *pLayoutClassName, - LayoutFactoryFunc pLayoutFactoryFunc) - { - instance()->doRegisterLayout(QLatin1String(pLayoutClassName), pLayoutFactoryFunc); - } - - inline QStringList Factory::registeredAppenders() - { - QMutexLocker locker(&instance()->mObjectGuard); - return instance()->mAppenderRegistry.keys(); - } - - inline QStringList Factory::registeredFilters() - { - QMutexLocker locker(&instance()->mObjectGuard); - return instance()->mFilterRegistry.keys(); - } - - inline QStringList Factory::registeredLayouts() - { - QMutexLocker locker(&instance()->mObjectGuard); - return instance()->mLayoutRegistry.keys(); - } - - inline void Factory::setObjectProperty(QObject *pObject, - const QString &rProperty, - const QString &rValue) - { - instance()->doSetObjectProperty(pObject, rProperty, rValue); - } - - inline void Factory::setObjectProperty(QObject *pObject, - const char *pProperty, - const QString &rValue) - { - instance()->doSetObjectProperty(pObject, QLatin1String(pProperty), rValue); - } - - inline void Factory::unregisterAppender(const QString &rAppenderClassName) - { - instance()->doUnregisterAppender(rAppenderClassName); - } - - inline void Factory::unregisterAppender(const char *pAppenderClassName) - { - instance()->doUnregisterAppender(QLatin1String(pAppenderClassName)); - } - - inline void Factory::unregisterFilter(const QString &rFilterClassName) - { - instance()->doUnregisterFilter(rFilterClassName); - } - - inline void Factory::unregisterFilter(const char *pFilterClassName) - { - instance()->doUnregisterFilter(QLatin1String(pFilterClassName)); - } - - inline void Factory::unregisterLayout(const QString &rLayoutClassName) - { - instance()->doUnregisterLayout(rLayoutClassName); - } - - inline void Factory::unregisterLayout(const char *pLayoutClassName) - { - instance()->doUnregisterLayout(QLatin1String(pLayoutClassName)); - } - -} // namespace Log4Qt - - -// Q_DECLARE_TYPEINFO(Log4Qt::Factory, Q_COMPLEX_TYPE); // use default - - -#endif // LOG4QT_HELPERS_FACTORY_H diff --git a/src/log4qt/src/log4qt/helpers/initialisationhelper.cpp b/src/log4qt/src/log4qt/helpers/initialisationhelper.cpp deleted file mode 100644 index e8ba59b..0000000 --- a/src/log4qt/src/log4qt/helpers/initialisationhelper.cpp +++ /dev/null @@ -1,185 +0,0 @@ -/****************************************************************************** - * - * package: Log4Qt - * file: initialisationhelper.cpp - * created: September 2007 - * author: Martin Heinrich - * - * - * changes Feb 2009, Martin Heinrich - * - Fixed VS 2008 unreferenced formal parameter warning by using - * Q_UNUSED in operator<<. - * - * - * Copyright 2007 - 2009 Martin Heinrich - * - * 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. - * - ******************************************************************************/ - - - -/****************************************************************************** - * Dependencies - ******************************************************************************/ - - -#include "log4qt/helpers/initialisationhelper.h" - -#include -#include -#include -#include -#include -#ifndef QT_NO_DATASTREAM -#include -#endif -#include "log4qt/helpers/datetime.h" -#include "log4qt/helpers/logerror.h" -#include "log4qt/loggingevent.h" - - - -namespace Log4Qt -{ - - - /************************************************************************** - *Declarations - **************************************************************************/ - - - - /************************************************************************** - * C helper functions - **************************************************************************/ - - - - /************************************************************************** - * Class implementation: InitialisationHelper - **************************************************************************/ - - - InitialisationHelper::InitialisationHelper() : - mStartTime(DateTime::currentDateTime().toMilliSeconds()), - mEnvironmentSettings() - { - doRegisterTypes(); - doInitialiseEnvironmentSettings(); - } - - - InitialisationHelper::~InitialisationHelper() - { - Q_ASSERT_X(false, "InitialisationHelper::~InitialisationHelper()", "Unexpected destruction of singleton object"); - } - - - LOG4QT_IMPLEMENT_INSTANCE(InitialisationHelper) - - - void InitialisationHelper::doInitialiseEnvironmentSettings() - { - // Is Process::systemEnvironment() safe to be used before a QCoreApplication - // object has been created? - - QStringList setting_keys; - setting_keys << QLatin1String("Debug"); - setting_keys << QLatin1String("DefaultInitOverride"); - setting_keys << QLatin1String("Configuration"); - setting_keys << QLatin1String("ConfiguratorClass"); - - QHash env_keys; - QString entry; - Q_FOREACH(entry, setting_keys) - env_keys.insert(QString::fromLatin1("log4qt_").append(entry).toUpper(), entry); - - QStringList sys_env = QProcess::systemEnvironment(); - Q_FOREACH(entry, sys_env) - { - int i = entry.indexOf(QLatin1Char('=')); - if (i == -1) - continue; - QString key = entry.left(i); - QString value = entry.mid(i + 1).trimmed(); - if (env_keys.contains(key)) - mEnvironmentSettings.insert(env_keys.value(key), value); - } - } - - - void InitialisationHelper::doRegisterTypes() - { - qRegisterMetaType("Log4Qt::LogError"); - qRegisterMetaType("Log4Qt::Level"); - qRegisterMetaType("Log4Qt::LoggingEvent"); - - #ifndef QT_NO_DATASTREAM - qRegisterMetaTypeStreamOperators("Log4Qt::LogError"); - qRegisterMetaTypeStreamOperators("Log4Qt::Level"); - qRegisterMetaTypeStreamOperators("Log4Qt::LoggingEvent"); - #endif - } - - - QString InitialisationHelper::doSetting(const QString &rKey, - const QString &rDefault) const - { - if (mEnvironmentSettings.contains(rKey)) - return mEnvironmentSettings.value(rKey); - - if (QCoreApplication::instance()) - { - QSettings s; - s.beginGroup(QLatin1String("Log4Qt")); - return s.value(rKey, rDefault).toString().trimmed(); - } - else - return rDefault; - } - - - bool InitialisationHelper::staticInitialisation() - { - instance(); - return true; - } - - - bool InitialisationHelper::msStaticInitialisation = staticInitialisation(); - - - - /************************************************************************** - * Implementation: Operators, Helper - **************************************************************************/ - - -#ifndef QT_NO_DEBUG_STREAM - QDebug operator<<(QDebug debug, - const InitialisationHelper &rInitialisationHelper) - { - Q_UNUSED(rInitialisationHelper); - debug.nospace() << "InitialisationHelper(" - << "starttime:" << InitialisationHelper::startTime() - << "(" << DateTime::fromMilliSeconds(InitialisationHelper::startTime()) << ")" - << "environmentsettings:" << InitialisationHelper::environmentSettings() - << ")"; - return debug.space(); - } -#endif // QT_NO_DEBUG_STREAM - - - -} // namespace Log4Qt diff --git a/src/log4qt/src/log4qt/helpers/initialisationhelper.h b/src/log4qt/src/log4qt/helpers/initialisationhelper.h deleted file mode 100644 index 95b370d..0000000 --- a/src/log4qt/src/log4qt/helpers/initialisationhelper.h +++ /dev/null @@ -1,435 +0,0 @@ -/****************************************************************************** - * - * package: Log4Qt - * file: initialisationhelper.h - * created: September 2007 - * author: Martin Heinrich - * - * - * changes: Sep 2008, Martin Heinrich: - * - Replaced usage of q_atomic_test_and_set_ptr with - * QBasicAtomicPointer - * - * - * Copyright 2007 - 2008 Martin Heinrich - * - * 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. - * - ******************************************************************************/ - -#ifndef LOG4QT_HELPERS_INITIALISATIONHELPER_H -#define LOG4QT_HELPERS_INITIALISATIONHELPER_H - - -/****************************************************************************** - * Dependencies - ******************************************************************************/ - -#include -#include -#include - -#if QT_VERSION >= QT_VERSION_CHECK(4, 4, 0) -# ifndef Q_ATOMIC_POINTER_TEST_AND_SET_IS_ALWAYS_NATIVE -# warning "QAtomicPointer test and set is not native. The macros Log4Qt::LOG4QT_GLOBAL_STATIC and Log4Qt::LOG4QT_IMPLEMENT_INSTANCE are not thread-safe." -# endif -#endif - - -/****************************************************************************** - * Declarations - ******************************************************************************/ - -class QMutex; - -namespace Log4Qt -{ - /*! - * LOG4QT_GLOBAL_STATIC declares a static function \a FUNCTION that - * returns a pointer to a singleton object of the type \a TYPE. - * - * The macro uses a static variable to store a pointer to the singleton - * object. On the first invocation an object of the type \a TYPE is created - * on the heap and the pointer is set. Any further invocations will return - * the stored pointer. If multiple threads are accessing the function - * without the pointer being set, each thread will create an object of the - * type \a TYPE. The threads that find the pointer already been set will - * delete their object. The singleton object will not be deleted during static - * de-initialisation. - * - * The following example uses a global global mutex object to synchronise - * access to a static member variable. - * - * \code - * #file: myclass.h - * - * class MyClass - * { - * public: - * MyClass(); - * ~MyClass(); - * private: - * static qint64 msObjectCount; - * } - * \endcode - * \code - * #file: myclass.cpp - * - * #include myclass.h - * - * LOG4QT_GLOBAL_STATIC(QMutex, class_guard) - * - * MyClass::MyClass() - * { - * QMutexLocker(class_guard()); - * msObjectCount++; - * } - * - * MyClass::~MyClass() - * { - * QMutexLocker(class_guard()); - * msObjectCount--; - * } - * - * qint64 MyClass::msObjectCount = 0; - * \endcode - * - * \note The function created by the macro is thread-safe. - * - * \sa \ref Log4Qt::LOG4QT_IMPLEMENT_INSTANCE "LOG4QT_IMPLEMENT_INSTANCE", - * \ref Log4Qt::InitialisationHelper "InitialisationHelper" - */ -#if QT_VERSION < QT_VERSION_CHECK(4, 4, 0) - #define LOG4QT_GLOBAL_STATIC(TYPE, FUNCTION) \ - static volatile TYPE *sp_global_static_##FUNCTION = 0; \ - TYPE *FUNCTION() \ - { \ - if (!sp_global_static_##FUNCTION) \ - { \ - TYPE *p_temp = new TYPE; \ - if (!q_atomic_test_and_set_ptr(&sp_global_static_##FUNCTION, \ - 0, p_temp)) \ - delete p_temp; \ - } \ - return const_cast(sp_global_static_##FUNCTION); \ - } -#elif QT_VERSION < QT_VERSION_CHECK(5, 0, 0) - #define LOG4QT_GLOBAL_STATIC(TYPE, FUNCTION) \ - static QBasicAtomicPointer sp_global_static_##FUNCTION = \ - Q_BASIC_ATOMIC_INITIALIZER(0); \ - TYPE *FUNCTION() \ - { \ - if (!sp_global_static_##FUNCTION) \ - { \ - TYPE *p_temp = new TYPE; \ - if (!sp_global_static_##FUNCTION.testAndSetOrdered(0, \ - p_temp)) \ - delete p_temp; \ - } \ - return sp_global_static_##FUNCTION; \ - } -#else - #define LOG4QT_GLOBAL_STATIC(TYPE, FUNCTION) \ - static QBasicAtomicPointer sp_global_static_##FUNCTION = \ - Q_BASIC_ATOMIC_INITIALIZER(0); \ - TYPE *FUNCTION() \ - { \ - if (!sp_global_static_##FUNCTION.loadAcquire()) \ - { \ - TYPE *p_temp = new TYPE; \ - if (!sp_global_static_##FUNCTION.testAndSetOrdered(0, \ - p_temp)) \ - delete p_temp; \ - } \ - return sp_global_static_##FUNCTION.loadAcquire(); \ - } -#endif - - /*! - * LOG4QT_IMPLEMENT_INSTANCE implements an instance function for a - * singleton class \a TYPE. - * - * The function works like the one created by - * \ref Log4Qt::LOG4QT_GLOBAL_STATIC "LOG4QT_GLOBAL_STATIC". - * - * The following example illustrates how to use the macro to create a - * singleton class: - * - * \code - * #file: mysingleton.h - * - * class MySingleton - * { - * private: - * MySingleton(); - * ~MySingleton(); - * public: - * MySingleton *instance(); - * } - * \endcode - * \code - * #file: mysingleton.cpp - * - * #include mysingleton.h - * - * MySingleton::MySingleton() - * {} - * - * MySingleton::~MySingleton() - * {} - * - * LOG4QT_IMPLEMENT_INSTANCE(MySingleton) - * - * \endcode - * - * \note The function created by the macro is thread-safe. - * - * \sa \ref Log4Qt::LOG4QT_GLOBAL_STATIC "LOG4QT_GLOBAL_STATIC", - * \ref Log4Qt::InitialisationHelper "InitialisationHelper" - */ -#if QT_VERSION < QT_VERSION_CHECK(4, 4, 0) - #define LOG4QT_IMPLEMENT_INSTANCE(TYPE) \ - static TYPE *sp_singleton_##TYPE = 0; \ - TYPE *TYPE::instance() \ - { \ - if (!sp_singleton_##TYPE) \ - { \ - TYPE *p_temp = new TYPE; \ - if (!q_atomic_test_and_set_ptr(&sp_singleton_##TYPE, \ - 0, p_temp)) \ - delete p_temp; \ - } \ - return sp_singleton_##TYPE; \ - } -#elif QT_VERSION < QT_VERSION_CHECK(5, 0, 0) - #define LOG4QT_IMPLEMENT_INSTANCE(TYPE) \ - static QBasicAtomicPointer sp_singleton_##TYPE = \ - Q_BASIC_ATOMIC_INITIALIZER(0); \ - TYPE *TYPE::instance() \ - { \ - if (!sp_singleton_##TYPE) \ - { \ - TYPE *p_temp = new TYPE; \ - if (!sp_singleton_##TYPE.testAndSetOrdered(0, p_temp)) \ - delete p_temp; \ - } \ - return sp_singleton_##TYPE; \ - } -#else - #define LOG4QT_IMPLEMENT_INSTANCE(TYPE) \ - static QBasicAtomicPointer sp_singleton_##TYPE = \ - Q_BASIC_ATOMIC_INITIALIZER(0); \ - TYPE *TYPE::instance() \ - { \ - if (!sp_singleton_##TYPE.loadAcquire()) \ - { \ - TYPE *p_temp = new TYPE; \ - if (!sp_singleton_##TYPE.testAndSetOrdered(0, p_temp)) \ - delete p_temp; \ - } \ - return sp_singleton_##TYPE.loadAcquire(); \ - } -#endif - - /*! - * \brief The class InitialisationHelper performs static initialisation - * tasks. - * - * The InitialisationHelper is either created on the first call or through - * static initialisation. It will capture the programs startup time, - * which can be retrieved using startTime(). The system environment - * is analysed for package related definitions. The result is available - * over environmentSettings(). The packages custom types are registered with - * the Qt type system. - * - * Settings for the package can be retrieved using setting(). Two macros - * are available to help with the creation of singletons / global static - * objects (\ref Log4Qt::LOG4QT_GLOBAL_STATIC "LOG4QT_GLOBAL_STATIC" and - * \ref Log4Qt::LOG4QT_IMPLEMENT_INSTANCE "LOG4QT_IMPLEMENT_INSTANCE"). - * - * \note All the functions declared in this class are thread-safe. - * - * \sa \ref Init "Initialization procedure", - */ - class InitialisationHelper - { - private: - InitialisationHelper(); - InitialisationHelper(const InitialisationHelper &rOther); // Not implemented - virtual ~InitialisationHelper(); - InitialisationHelper &operator=(const InitialisationHelper &rOther); // Not implemented - - public: - - /*! - * Returns a hash with the settings retrieved from the system - * environment on startup. - * - * The following table shows the environment variables taken into - * account and the setting key used for them. - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - *
Environment variable Setting key
LOG4QT_DEBUG Debug
LOG4QT_DEFAULTINITOVERRIDE DefaultInitOverride
LOG4QT_CONFIGURATION Configuration
LOG4QT_CONFIGURATORCLASS ConfiguratorClass
- * - * \sa \ref Env "Environment Variables", - * setting() - */ - static QHash environmentSettings(); - - /*! - * Returns the InitialisationHelper instance. - */ - static InitialisationHelper *instance(); - - /*! - * Returns the value for the setting \a rKey or \a rDefault, if it is - * not defined. - * - * A setting can be either defined by an environment variable or by a - * key in the application setting. The function will first test the - * settings made by environment variables for the key \a rKey using - * environmentSettings(). If the key is not present and a - * QCoreApplication exists, the application settings are tested for - * the key \a rKey in the group \c %Log4Qt. - * - * The following setting exists: - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - *
Setting key Description
Debug The variable controls the Level value for the logger - * LogManager::logLogger(). If the value is a valid Level string, - * the level for the logger is set to the level. If the value is not - * a valid Level string, \ref Level::DEBUG_INT "DEBUG_INT" is used. - * Otherwise \ref Level::ERROR_INT "ERROR_INT" is used.
DefaultInitOverride The variable controls the \ref Init "initialization procedure" - * performed by the \ref LogManager "LogManager" on startup. - * If it is set to any other value then \c false the \ref Init - * "initialization procedure" is skipped.
Configuration Specifies the configuration file used for initialising the package.
ConfiguratorClass Specifies the configurator class used for initialising the package.
- * - * \sa environmentSettings(), \ref Env "Environment Variables", - * \ref Init "Initialization procedure", - * LogManager::configureLogLogger(), LogManager::startup() - */ - static QString setting(const QString &rKey, - const QString &rDefault = QString()); - - /*! - * Returns the start time of the program as the number of milliseconds - * that have passed since 1970-01-01T00:00:00,000, Coordinated - * Universal Time (Qt::UTC). - * - * \sa DateTime::fromMilliSeconds(), - * DateTime::toMilliSeconds() - */ - static qint64 startTime(); - - private: - void doInitialiseEnvironmentSettings(); - void doRegisterTypes(); - QString doSetting(const QString &rKey, - const QString &rDefault) const; - static bool shutdown(); - static bool staticInitialisation(); - - private: - // QMutex mObjectGuard; - const qint64 mStartTime; - QHash mEnvironmentSettings; - static bool msStaticInitialisation; - -#ifndef QT_NO_DEBUG_STREAM - // Needs to be friend to access details - friend QDebug operator<<(QDebug debug, - const InitialisationHelper &rInitialisationHelper); -#endif // QT_NO_DEBUG_STREAM - }; - - - /************************************************************************** - * Operators, Helper - **************************************************************************/ - -#ifndef QT_NO_DEBUG_STREAM - /*! - * \relates InitialisationHelper - * - * Writes all object member variables to the given debug stream \a rDebug and - * returns the stream. - * - * - * %InitialisationHelper(InitialisationHelper(starttime:1193883677438( - * QDateTime("Wed Oct 31 21:21:17 2007") ) - * environmentsettings: QHash(("configuration", "\myapp.log4j") - * ("Debug", "DEBUG")) ) ) - * - * \sa QDebug, InitialisationHelper::logManager() - */ - QDebug operator<<(QDebug debug, - const InitialisationHelper &rInitialisationHelper); -#endif // QT_NO_DEBUG_STREAM - - - /************************************************************************** - * Inline - **************************************************************************/ - - inline QHash InitialisationHelper::environmentSettings() - { // QMutexLocker locker(&instance()->mObjectGuard); // Constant for object lifetime - return instance()->mEnvironmentSettings; } - - inline QString InitialisationHelper::setting(const QString &rKey, - const QString &rDefault) - { // QMutexLocker locker(&instance()->mObjectGuard); // Reentrant and const - return instance()->doSetting(rKey, rDefault); } - - inline qint64 InitialisationHelper::startTime() - { // QMutexLocker locker(&instance()->mObjectGuard); // Constant for object lifetime - return instance()->mStartTime; } - -} // namespace Log4Qt - - -// Q_DECLARE_TYPEINFO(Log4Qt::InitialisationHelper, Q_COMPLEX_TYPE); // use default - - -#endif // LOG4QT_HELPERS_INITIALISATIONHELPER_H diff --git a/src/log4qt/src/log4qt/helpers/logerror.cpp b/src/log4qt/src/log4qt/helpers/logerror.cpp deleted file mode 100644 index f78d2ab..0000000 --- a/src/log4qt/src/log4qt/helpers/logerror.cpp +++ /dev/null @@ -1,354 +0,0 @@ -/****************************************************************************** - * - * package: Log4Qt - * file: logerror.cpp - * created: September 2007 - * author: Martin Heinrich - * - * - * Copyright 2007 Martin Heinrich - * - * 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. - * - ******************************************************************************/ - - - -/****************************************************************************** - * Dependencies - *****************************************************************************/ - - -#include "log4qt/helpers/logerror.h" - -#include -#include -#include -#include -#include -#include -#include -#include "log4qt/helpers/initialisationhelper.h" - - -namespace Log4Qt -{ - - - /************************************************************************** - * Declarations - **************************************************************************/ - - - typedef QThreadStorage ThreadError; - - - - /************************************************************************** - * C helper functions - **************************************************************************/ - - - LOG4QT_GLOBAL_STATIC(ThreadError, thread_error) - - - - /************************************************************************** - * Class implementation: LogError - **************************************************************************/ - - - LogError::LogError() : - mCode(0), - mContext(), - mMessage(), - mSymbol(), - mArgs(), - mCausingErrors() - { - } - - - LogError::LogError(const QString &rMessage, - int code, - const QString &rSymbol, - const QString &rContext) : - mCode(code), - mContext(rContext), - mMessage(cleanMessage(rMessage)), - mSymbol(rSymbol), - mArgs(), - mCausingErrors() - { - } - - - LogError::LogError(const char *pMessage, - int code, - const char *pSymbol, - const char *pContext, - Encoding encoding) : - mCode(code), - mContext(QString::fromLatin1(pContext)), - mMessage(), - mSymbol(QString::fromLatin1(pSymbol)), - mArgs(), - mCausingErrors() - { - switch(encoding) - { - case LATIN1: - mMessage = QString::fromLatin1(pMessage); - break; - case CODECFORTR: -#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0) - mMessage = QTextCodec::codecForTr()->toUnicode(pMessage); -#else - mMessage = QString::fromUtf8(pMessage); -#endif - break; - case UNICODEUTF8: - mMessage = QString::fromUtf8(pMessage); - break; - default: - Q_ASSERT_X(false, "LogError::LogError", "Unkown encoding constant"); - mMessage = QString::fromLatin1(pMessage); - } - mMessage = cleanMessage(mMessage); - - if (mSymbol == QString::number(mCode)) - mSymbol.clear(); - } - - - QString LogError::translatedMessage() const - { -#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0) - return QCoreApplication::translate(mContext.toLatin1(), mMessage.toUtf8().data(), 0, QCoreApplication::UnicodeUTF8); -#else - return QCoreApplication::translate(mContext.toLatin1(), mMessage.toUtf8().data(), 0); -#endif - } - - - LogError LogError::lastError() - { - if (!thread_error()->hasLocalData()) - return LogError(); - else - return *thread_error()->localData(); - } - - - void LogError::setLastError(const LogError &rLogError) - { - if (!thread_error()->hasLocalData()) - thread_error()->setLocalData(new LogError); - - *thread_error()->localData() = rLogError; - } - - - QString LogError::toString() const - { - QString result = messageWithArgs(); - - QString context_symbol = mContext; - if (!context_symbol.isEmpty() && !mSymbol.isEmpty()) - context_symbol.append(QLatin1String("::")); - context_symbol.append(mSymbol); - - if (!context_symbol.isEmpty() || mCode) - { - result.append(QLatin1String(" (")); - if (!context_symbol.isEmpty()) - result.append(context_symbol); - if (!context_symbol.isEmpty() && mCode) - result.append(QLatin1String(", ")); - if (mCode) - result.append(QString::number(mCode)); - result.append(QLatin1String(")")); - } - - if (!mCausingErrors.isEmpty()) - { - QString causing_errors_str = QLatin1String(": ") + mCausingErrors.at(0).toString(); - int i = 1; - while (i < mCausingErrors.count()) - { - causing_errors_str.append(QLatin1String(", ")).append(mCausingErrors.at(i).toString()); - i++; - } - result.append(causing_errors_str); - } - - return result; - } - - - QString LogError::insertArgs(const QString &rMessage) const - { - QString result; - - /* - - // Don't use a loop to be able to handle arguments that conatin strings - // like %1. - // Using this method only 9 arguments can be handled as the %1 - // in %11 gets also replaced with the first argument. - - switch (mArgs.count()) - { - case 0: - break; - case 1: - result = rMessage.arg(mArgs.at(0)); - break; - case 2: - result = rMessage.arg(mArgs.at(0), mArgs.at(1)); - break; - case 3: - result = rMessage.arg(mArgs.at(0), mArgs.at(1), mArgs.at(2)); - break; - case 4: - result = rMessage.arg(mArgs.at(0), mArgs.at(1), mArgs.at(2), mArgs.at(3)); - break; - case 5: - result = rMessage.arg(mArgs.at(0), mArgs.at(1), mArgs.at(2), mArgs.at(3), mArgs.at(4)); - break; - case 6: - result = rMessage.arg(mArgs.at(0), mArgs.at(1), mArgs.at(2), mArgs.at(3), mArgs.at(4), mArgs.at(5)); - break; - case 7: - result = rMessage.arg(mArgs.at(0), mArgs.at(1), mArgs.at(2), mArgs.at(3), mArgs.at(4), mArgs.at(5), mArgs.at(6)); - break; - case 8: - result = rMessage.arg(mArgs.at(0), mArgs.at(1), mArgs.at(2), mArgs.at(3), mArgs.at(4), mArgs.at(5), mArgs.at(6), mArgs.at(7)); - break; - default: - result = rMessage.arg(mArgs.at(0), mArgs.at(1), mArgs.at(2), mArgs.at(3), mArgs.at(4), mArgs.at(5), mArgs.at(6), mArgs.at(7), mArgs.at(8)); - break; - } - - if (mArgs.count() > 9) - { - int i = 9; - while(i < mArgs.count()) - { - result = result.arg(mArgs.at(i)); - i++; - } - } - */ - - result = rMessage; - QVariant arg; - Q_FOREACH(arg, mArgs) - result = result.arg(arg.toString()); - return result; - } - - - QString LogError::cleanMessage(const QString &rMessage) - { - if (rMessage.isEmpty()) - return rMessage; - - QString result = rMessage; - if (rMessage.at(rMessage.size() - 1) == QLatin1Char('.')) - result = rMessage.left(rMessage.size() - 1); - return result; - } - - - - /************************************************************************** - * Implementation: Operators, Helper - **************************************************************************/ - - -#ifndef QT_NO_DATASTREAM - QDataStream &operator<<(QDataStream &rStream, - const LogError &rLogError) - { - QBuffer buffer; - buffer.open(QIODevice::WriteOnly); - QDataStream stream(&buffer); - - // version - quint16 version = 0; - stream << version; - // version 0 data - stream << rLogError.mCode - << rLogError.mContext - << rLogError.mMessage - << rLogError.mSymbol - << rLogError.mArgs - << rLogError.mCausingErrors; - - buffer.close(); - rStream << buffer.buffer(); - return rStream; - } - - - QDataStream &operator>>(QDataStream &rStream, - LogError &rLogError) - { - QByteArray array; - rStream >> array; - QBuffer buffer(&array); - buffer.open(QIODevice::ReadOnly); - QDataStream stream(&buffer); - - // version - quint16 version; - stream >> version; - // Version 0 data - QString level; - QString logger; - stream >> rLogError.mCode - >> rLogError.mContext - >> rLogError.mMessage - >> rLogError.mSymbol - >> rLogError.mArgs - >> rLogError.mCausingErrors; - - buffer.close(); - return rStream; - } -#endif // QT_NO_DATASTREAM - - -#ifndef QT_NO_DEBUG_STREAM - QDebug operator<<(QDebug debug, - const LogError &rLogError) - { - // Escape % sign - QString message = rLogError.message(); - message.replace(QLatin1String("%"), QLatin1String("%%")); - - debug.nospace() << "LogError(" - << "code:" << rLogError.code() << " " - << "context:" << rLogError.context() << " " - << "message:" << message << " " - << "symbol:" << rLogError.symbol() << " " - << "args:" << rLogError.args() - << "translatedMessage:" << rLogError.translatedMessage() - << ")"; - return debug.maybeSpace(); - } -#endif // QT_NO_DEBUG_STREAM - - -} // namespace Log4Qt diff --git a/src/log4qt/src/log4qt/helpers/logerror.h b/src/log4qt/src/log4qt/helpers/logerror.h deleted file mode 100644 index 06d1a67..0000000 --- a/src/log4qt/src/log4qt/helpers/logerror.h +++ /dev/null @@ -1,550 +0,0 @@ -/****************************************************************************** - * - * package: Log4Qt - * file: logerror.h - * created: September 2007 - * author: Martin Heinrich - * - * - * Copyright 2007 Martin Heinrich - * - * 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. - * - ******************************************************************************/ - -#ifndef LOG4QT_LOGERROR_H -#define LOG4QT_LOGERROR_H - - -/****************************************************************************** - * Dependencies - ******************************************************************************/ - -#include -#include - - -/****************************************************************************** - * Declarations - ******************************************************************************/ - -namespace Log4Qt -{ - /*! - * Creates an LogError object with the error message \a message, the error - * code \a code and the context \a context. The symbol of the error is - * set to \a code as string value. - * - * The following example logs an error, if a character is not a digit. - * - * \code - * if (!c.isDigit()) - * { - * Error e = LOG4QT_ERROR(QT_TR_NOOP("Found character '%1' where digit was expected."), - * LAYOUT_EXPECTED_DIGIT_ERROR, - * "Log4Qt::PatternFormatter"); - * e << QString(c); - * logger()->error(e); - * } - * \endcode - */ - #define LOG4QT_ERROR(message, code, context) \ - LogError(message, code, #code, context) - - /*! - * Creates an LogError object with the error message \a message and the - * error code \a code. The symbol of the error is set to \a code as string - * value. The context is set to the class name of the current object. The - * current objects class must be derived from QObject. - * - * The following example handles an error while opening a file. - * - * \code - * if (!mpFile->open(mode)) - * { - * LogError e = LOG4QT_QCLASS_ERROR(QT_TR_NOOP("Unable to open file '%1' for appender '%2'"), - * APPENDER_OPENING_FILE_ERROR); - * e << mFileName << name(); - * e.addCausingError(LogError(mpFile->errorString(), mpFile->error())); - * logger()->error(e); - * return; - * } - * \endcode - */ - #define LOG4QT_QCLASS_ERROR(message, code) \ - LogError(message, code, #code, this->metaObject()->className()) - - /*! - * \brief The class LogError represents an error. - * - * The class error allows storing error information in a structured way. - * The error message is stored separately from the information that may be - * substituted into the message string. This way it is possible to access - * all information after the error has been raised. It also allows to - * translate the error at a later point in time or to get a translated and - * a not translated error text (e.g. translated for the UI and not - * translated for a log). - * - * The message is accessed using message() and setMessage(). Arguments for - * the message can be added using addArg() or operator<<(). The arguments - * can be retrieved using args(). The message with substituted arguments - * is returned by messageWithArgs(). - * - * An error code can be set as integer value code() and/or a symbolic value - * symbol(). - * - * To allow the translation of the message the error stores the translation - * context (context(), setContext()). The translated message can be accessed - * using translatedMessage() or using translatedMessageWithArgs(), if it - * should contain the arguments. - * - * An error can have one or more related errors that caused it. An error is - * related using addCausingError(). All causing errors can be retrieved using - * causingErrors(). - * - * A per thread error can be maintained using lastError() and setLastError(). - * - * There are two macros avaiable to simplify the error creation. The macro - * \ref Log4Qt::LOG4QT_ERROR "LOG4QT_ERROR" is used with classes not derived - * from QObject. The macro \ref Log4Qt::LOG4QT_QCLASS_ERROR "LOG4QT_QCLASS_ERROR" - * is used with classes derived from QObject. - */ - class LogError - { - public: - - /*! - * The enum Encoding defines the 8-bit encoding of a character string - * arguments to \ref LogError::LogError(const char *, int, const char *, - * const char *, Encoding) "LogError::LogError()". - * - * \sa \ref LogError::LogError(const char *, int, const char *, const char *, Encoding) "LogError::LogError()" - */ - enum Encoding - { - /*! LATIN-1 */ - LATIN1, - /*! - * The encoding specified by QTextCodec::codecForTr() - * (Latin-1 if none has been set). - */ - CODECFORTR, - /*! UTF-8 */ - UNICODEUTF8 - }; - Q_ENUMS(Encoding) - - /*! - * Creates an empty error. The error code is set to 0 and all other - * members are set to be empty. - * - * \sa isEmpty() - */ - LogError(); - - /*! - * Creates an error with the Message \a rMessage and the error code - * \a code. The symbol for the error code is set to \a rSymbol and the - * context to \a rContext. - * - * \a rContext must be string that can be converted to Latin-1. The - * Latin-1 representation of the string is used with - * QApplication::translate(), if a translation for \a rMessage is - * requested. - * - * \sa translatedMessage(), translatedMessageWithArgs() - */ - LogError(const QString &rMessage, - int code = 0, - const QString &rSymbol = QString(), - const QString &rContext = QString()); - - /*! - * Creates an error with the Message \a pMessage and the error code - * \a code. The symbol for the error code is set to \a pSymbol and the - * context to \a pContext. - * - * \a encoding specifies the encoding of \a pMessage. \a pSymbol and - * \a pContext are expected to be Latin-1. - * - * \note To support the macros \ref Log4Qt::LOG4QT_ERROR "LOG4QT_ERROR" - * and \ref Log4Qt::LOG4QT_QCLASS_ERROR "LOG4QT_QCLASS_ERROR" - * the function tests, if \a pSymbol is the string representation of - * \a code. If it is, the symbol is set to be empty. Otherwise symbol - * is set to \a pSymbol. - * - * \sa translatedMessage(), translatedMessageWithArgs() - */ - LogError(const char *pMessage, - int code = 0, - const char *pSymbol = 0, - const char *pContext = 0, - Encoding encoding = LATIN1); - - // LogError(const LogError &rOther); // Use compiler default - // virtual ~LogError(); // Use compiler default - // LogError &operator=(const LogError &rOther); // Use compiler default - - /*! - * Returns the error code. - * - * \sa setCode() - */ - int code() const; - - /*! - * Returns the context for the error. - * - * \sa setContext() - */ - QString context() const; - - /*! - * Returns the error message. - * - * \sa setMessage() - */ - QString message() const; - - /*! - * Returns the symbol for the error code. - * - * \sa setSymbol() - */ - QString symbol() const; - - /*! - * Returns the translated error message. - * - * The translated message is created by calling - * QCoreApplication::translate() using context().toLatin1() as - * context and message.toUtf8() as message. - * - * \sa translatedMessageWithArgs() - */ - QString translatedMessage() const; - - /*! - * Sets the error code to \a code. - * - * \sa code() - */ - void setCode(int code); - - /*! - * Sets the context to \a rClassName. - * - * \a rContext must be string that can be converted to Latin-1. The - * Latin-1 representation of the string is used with - * QApplication::translate(), if a translation for \a rMessage is - * requestd. - * - * \sa context(), translatedMessage(), translatedMessageWithArgs() - */ - void setContext(const QString &rClassName); - - /*! - * Sets the error message to \a rMessage - * - * \sa message() - */ - void setMessage(const QString &rMessage); - - /*! - * Sets the symbol for the error code to \a rSymbol. - * - * \sa symbol() - */ - void setSymbol(const QString &rSymbol); - - /*! - * Returns the last error set for the current thread using - * setLastError(). - * - * \note: This function is thread-safe. - * - * \sa setLastError() - */ - static LogError lastError(); - - /*! - * Sets the last error for the current thread to \a rLogError. - * - * \note: This function is thread-safe. - * - * \sa lastError() - */ - static void setLastError(const LogError &rLogError); - - /*! - * Appends \a rArg to the list of arguments and returns a reference to - * this error. - * - * \sa operator<<(), args(), clearArgs() - */ - LogError &addArg(const QVariant &rArg); - - /*! - * This is an overloaded member function, provided for convenience. - */ - LogError &addArg(int arg); - - /*! - * This is an overloaded member function, provided for convenience. - */ - LogError &addArg(const QString &rArg); - - /*! - * Appends \a rLogError to the list of causing errors and returns a - * reference to this error. - * - * \sa causingErrors(), clearCausingErrors() - */ - LogError &addCausingError(const LogError &rLogError); - - /*! - * Returns the list of arguments that have been added to this error. - * - * \sa addArg(), operator<<(), clearArgs() - */ - QList args() const; - - /*! - * Returns the list of causing errors that have been added to this error. - * - * \sa addArg(), operator<<(), clearArgs() - */ - QList causingErrors() const; - - /*! - * Clears the list of arguments that have been added to this error. - * - * \sa addArg(), operator<<(), args() - */ - void clearArgs(); - - /*! - * Clears the list of causing errors that have been added to this error. - * - * \sa addCausingError(), causingErrors() - */ - void clearCausingErrors(); - - /*! - * Returns true, if the error code is 0 and the message is empty. - * Otherwise it returns false. - * - * \sa code(), message() - */ - bool isEmpty() const; - - /*! - * Returns the message with arguments. The arguments are incoorporated - * into the messag using QString::arg(). - * - * \sa QString::arg(), translatedMessageWithArgs() - */ - QString messageWithArgs() const; - - /*! - * Returns the translated message with arguments. The arguments are - * incoorporated into the messag using QString::arg(). - * - * \sa QString::arg(), messageWithArgs(), translatedMessage() - */ - QString translatedMessageWithArgs() const; - - /*! - * Appends \a rArg to the list of arguments and returns a reference to - * this error. - * - * \sa addArg() - */ - LogError &operator<<(const QVariant &rArg); - - /*! - * This is an overloaded member function, provided for convenience. - */ - LogError &operator<<(int arg); - - /*! - * This is an overloaded member function, provided for convenience. - */ - LogError &operator<<(const QString &rArg); - - /*! - * Returns a string representation of the error. - * - * The string has the following format: - * - * - * message (context::symbol, code): causing_error, causing_error - * - * - * If members are empty they are omitted: - * - Omit context, if empty - * - Omit symbol, if empty - * - Omit double colon with context and symbol, if both are empty - * - Omit code, if 0 - * - Omit bracket with context/symbol and code, if all are empty - * - Omit colon with causing errors, if no causing errors exist - */ - QString toString() const; - - private: - QString insertArgs(const QString &rMessage) const; - QString cleanMessage(const QString &rMessage); - - private: - int mCode; - QString mContext; - QString mMessage; - QString mSymbol; - QList mArgs; - QList mCausingErrors; - -#ifndef QT_NO_DATASTREAM - // Needs to be friend to stream objects - friend QDataStream &operator<<(QDataStream &rStream, - const LogError &rLogError); - friend QDataStream &operator>>(QDataStream &rStream, - LogError &rLogError); -#endif // QT_NO_DATASTREAM - }; - - - /************************************************************************** - * Operators, Helper - **************************************************************************/ - -#ifndef QT_NO_DATASTREAM - /*! - * \relates LogError - * - * Writes the given error \a rLogError to the given stream \a rStream, - * and returns a reference to the stream. - */ - QDataStream &operator<<(QDataStream &rStream, - const LogError &rLogError); - - /*! - * \relates LogError - * - * Reads an error from the given stream \a rStream into the given - * error \a rLogError, and returns a reference to the stream. - */ - QDataStream &operator>>(QDataStream &rStream, - LogError &rLogError); -#endif // QT_NO_DATASTREAM - -#ifndef QT_NO_DEBUG_STREAM - /*! - * \relates LogError - * - * Writes all object member variables to the given debug stream \a debug and - * returns the stream. - * - * - * %LogError(code:7 context:"Log4Qt::FileAppender" - * message:"Unable to open file '%1' for appender '%2'" - * symbol:"APPENDER_OPENING_FILE_ERROR" - * args:(QVariant(QString, "G:\logs\client.log") , QVariant(QString, "Client FileAppender") ) - * translatedMessage: "Unable to open file '%1' for appender '%2'" ) - * - * - * \sa QDebug - */ - QDebug operator<<(QDebug debug, - const LogError &rLogError); -#endif // QT_NO_DEBUG_STREAM - - - /************************************************************************** - * Inline - **************************************************************************/ - - inline int LogError::code() const - { return mCode; } - - inline QString LogError::context() const - { return mContext; } - - inline QString LogError::message() const - { return mMessage; } - - inline QString LogError::symbol() const - { return mSymbol; } - - inline void LogError::setCode(int code) - { mCode = code; } - - inline void LogError::setContext(const QString &rContext) - { mContext = rContext; } - - inline void LogError::setMessage(const QString &rMessage) - { mMessage = cleanMessage(rMessage); } - - inline void LogError::setSymbol(const QString &rSymbol) - { mSymbol = rSymbol; } - - inline LogError &LogError::addArg(const QVariant &rArg) - { mArgs << rArg; return *this; } - - inline LogError &LogError::addArg(int arg) - { mArgs << QVariant(arg); return *this; } - - inline LogError &LogError::addArg(const QString &rArg) - { mArgs << QVariant(rArg); return *this; } - - inline LogError &LogError::addCausingError(const LogError &rLogError) - { mCausingErrors << rLogError; return *this; } - - inline QList LogError::args() const - { return mArgs; } - - inline void LogError::clearArgs() - { mArgs.clear(); } - - inline void LogError::clearCausingErrors() - { mCausingErrors.clear(); } - - inline QList LogError::causingErrors() const - { return mCausingErrors; } - - inline bool LogError::isEmpty() const - { return mCode || !mMessage.isEmpty(); } - - inline QString LogError::messageWithArgs() const - { return insertArgs(message()); } - - inline QString LogError::translatedMessageWithArgs() const - { return insertArgs(translatedMessage()); } - - inline LogError &LogError::operator<<(const QVariant &rArg) - { return addArg(rArg); } - - inline LogError &LogError::operator<<(int arg) - { return addArg(arg); } - - inline LogError &LogError::operator<<(const QString &rArg) - { return addArg(rArg); } - - -} // namespace Log4Qt - - -Q_DECLARE_METATYPE(Log4Qt::LogError) -Q_DECLARE_TYPEINFO(Log4Qt::LogError, Q_MOVABLE_TYPE); - - -#endif // LOG4QT_ERROR_H diff --git a/src/log4qt/src/log4qt/helpers/logobject.cpp b/src/log4qt/src/log4qt/helpers/logobject.cpp deleted file mode 100644 index 44f1121..0000000 --- a/src/log4qt/src/log4qt/helpers/logobject.cpp +++ /dev/null @@ -1,74 +0,0 @@ -/****************************************************************************** - * - * package: Log4Qt - * file: logobject.cpp - * created: September 2007 - * author: Martin Heinrich - * - * - * Copyright 2007 Martin Heinrich - * - * 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. - * - ******************************************************************************/ - - -/****************************************************************************** - * Dependencies - ******************************************************************************/ - - -#include "log4qt/helpers/logobject.h" - -#include - - - -namespace Log4Qt -{ - - - /************************************************************************** - * Declarations - **************************************************************************/ - - - - /************************************************************************** - * C helper functions - **************************************************************************/ - - - - /************************************************************************** - * Class implementation: LogObject - **************************************************************************/ - - - - /************************************************************************** - * Implementation: Operators, Helper - **************************************************************************/ - - -#ifndef QT_NO_DEBUG_STREAM - QDebug operator<<(QDebug debug, - const LogObject &rLogObject) - { - return rLogObject.debug(debug); - } -#endif // QT_NO_DEBUG_STREAM - - - -} // namespace Log4Qt diff --git a/src/log4qt/src/log4qt/helpers/logobject.h b/src/log4qt/src/log4qt/helpers/logobject.h deleted file mode 100644 index 97b02c5..0000000 --- a/src/log4qt/src/log4qt/helpers/logobject.h +++ /dev/null @@ -1,217 +0,0 @@ -/****************************************************************************** - * - * package: Log4Qt - * file: logobject.h - * created: September 2007 - * author: Martin Heinrich - * - * - * changes: Sep 2008, Martin Heinrich: - * - Replaced usage of q_atomic_increment and q_atomic_decrement - * with QAtomicInt. - * Feb 2009, Martin Heinrich - * - Fixed a problem where the pParent parameter of the constructor - * was not passed on to the QObject constructor - * - * - * Copyright 2007 - 2009 Martin Heinrich - * - * 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. - * - ******************************************************************************/ - -#ifndef LOG4QT_LOGOBJECT_H -#define LOG4QT_LOGOBJECT_H - - -/****************************************************************************** - * Dependencies - ******************************************************************************/ - -#include - -#include "log4qt/helpers/classlogger.h" -#if QT_VERSION >= QT_VERSION_CHECK(4, 4, 0) -# include -# ifndef Q_ATOMIC_INT_REFERENCE_COUNTING_IS_ALWAYS_NATIVE -# warning "QAtomicInt reference counting is not native. The class Log4Qt::LogObject is not thread-safe." -# endif -#endif - - -namespace Log4Qt -{ - - class Logger; - - /*! - * \brief The class LogObject is the common base class for many classes - * in the package. - * - * The class inherits QObject to allow its subclass to be accessed using - * the Qt property system. - * - * LogObject objects provide a reference counter. A reference to the - * object is established by calling retain() and freed by calling - * release(). The object will delete itself when the reference counter - * is decremented to 0. - * - * A class specific logger can be accessed over logger(). - * - * The class also implements generic streaming to QDebug. Streaming an - * object to QDebug will invoke debug() to create class specific output. - * - * \note All the functions declared in this class are thread-safe. - * - * \sa \ref Ownership "Object ownership", - * LOG4QT_DECLARE_QCLASS_LOGGER - */ - class LogObject : public QObject - { - Q_OBJECT - - public: - /*! - * Creates a LogObject which is a child of \a pObject. - */ - LogObject(QObject *pObject = 0); - - /*! - * Destroys the LogObject. - */ - virtual ~LogObject(); - - private: - LogObject(const LogObject &rOther); // Not implemented - LogObject &operator=(const LogObject &rOther); // Not implemented - - public: - /*! - * Returns the value of the reference counter. - */ - int referenceCount() const; - - /*! - * Decrements the reference count of the object. If the reference count - * count reaches zero and the object does not have a parent the object - * is deleted. - */ - void release(); - - /*! - * Increments the reference count of the object. - */ - void retain(); - - protected: - #ifndef QT_NO_DEBUG_STREAM - /*! - * Writes all object member variables to the given debug stream - * \a rDebug and returns the stream. - * - * The member function is used by - * QDebug operator<<(QDebug debug, const LogObject &rLogObject) to - * generate class specific output. - * - * \sa QDebug operator<<(QDebug debug, const LogObject &rLogObject) - */ - virtual QDebug debug(QDebug &rDebug) const = 0; - - // Needs to be friend to access internal data - friend QDebug operator<<(QDebug debug, - const LogObject &rLogObject); - #endif // QT_NO_DEBUG_STREAM - - /*! - * Returns a pointer to a Logger named after of the object. - * - * \sa Logger::logger(const char *pName) - */ - Logger* logger() const; - - private: -#if QT_VERSION < QT_VERSION_CHECK(4, 4, 0) - volatile int mReferenceCount; -#else - mutable QAtomicInt mReferenceCount; -#endif - mutable ClassLogger mLog4QtClassLogger; - }; - - - /************************************************************************** - * Operators, Helper - **************************************************************************/ - - #ifndef QT_NO_DEBUG_STREAM - /*! - * \relates LogObject - * - * Writes all object member variables to the given debug stream \a debug - * and returns the stream. - * - * To handle sub-classing the function uses the virtual member function - * debug(). This allows each class to generate its own output. - * - * \sa QDebug, debug() - */ - QDebug operator<<(QDebug debug, - const LogObject &rLogObject); - #endif - - - /************************************************************************** - * Inline - **************************************************************************/ - - inline LogObject::LogObject(QObject *pParent) : - QObject(pParent), - mReferenceCount() - {} - - inline LogObject::~LogObject() - {} - - inline int LogObject::referenceCount() const -#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0) - { return mReferenceCount; } -#else - { return mReferenceCount.loadAcquire(); } -#endif - - inline void LogObject::release() -#if QT_VERSION < QT_VERSION_CHECK(4, 4, 0) - { if ((q_atomic_decrement(&mReferenceCount) == 0) && !parent()) - delete(this); } -#else - { if (!mReferenceCount.deref()) - delete(this); } -#endif - - inline void LogObject::retain() -#if QT_VERSION < QT_VERSION_CHECK(4, 4, 0) - { q_atomic_increment(&mReferenceCount); } -#else - { mReferenceCount.ref(); } -#endif - - inline Logger *LogObject::logger() const - { return mLog4QtClassLogger.logger(this); } - -} // namespace Log4Qt - - -// Q_DECLARE_TYPEINFO(Log4Qt::LogObject, Q_COMPLEX_TYPE); // Use default - - -#endif // LOG4QT_LOGOBJECT_H diff --git a/src/log4qt/src/log4qt/helpers/logobjectptr.cpp b/src/log4qt/src/log4qt/helpers/logobjectptr.cpp deleted file mode 100644 index 8084a79..0000000 --- a/src/log4qt/src/log4qt/helpers/logobjectptr.cpp +++ /dev/null @@ -1,65 +0,0 @@ -/****************************************************************************** - * - * package: Log4Qt - * file: logobjectptr.cpp - * created: September 2007 - * author: Martin Heinrich - * - * - * Copyright 2007 Martin Heinrich - * - * 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. - * - ******************************************************************************/ - - -/****************************************************************************** - * Dependencies - ******************************************************************************/ - - -#include "log4qt/helpers/logobjectptr.h" - -#include - - - -namespace Log4Qt -{ - - - /************************************************************************** - * Declarations - **************************************************************************/ - - - - /************************************************************************** - * C helper functions - **************************************************************************/ - - - - /************************************************************************** - * Class implementation: LogObjectPtr - **************************************************************************/ - - - - /************************************************************************** - * Implementation: Operators, Helper - **************************************************************************/ - - - -} // namespace Log4Qt diff --git a/src/log4qt/src/log4qt/helpers/logobjectptr.h b/src/log4qt/src/log4qt/helpers/logobjectptr.h deleted file mode 100644 index 6a8b613..0000000 --- a/src/log4qt/src/log4qt/helpers/logobjectptr.h +++ /dev/null @@ -1,187 +0,0 @@ -/****************************************************************************** - * - * package: Log4Qt - * file: logobjectptr.h - * created: September 2007 - * author: Martin Heinrich - * - * - * Copyright 2007 Martin Heinrich - * - * 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. - * - ******************************************************************************/ - -#ifndef LOG4QT_LOGOBJECTPTR_H -#define LOG4QT_LOGOBJECTPTR_H - - -/****************************************************************************** - * Dependencies - ******************************************************************************/ - -#include "log4qt/helpers/logobject.h" - -namespace Log4Qt -{ - /*! - * \brief The class LogObjectPtr implements automatic reference counting - * for LogObject objects. - */ - template - class LogObjectPtr - { - public: - /*! - * Constructs a 0 LogObject pointer. - */ - LogObjectPtr(); - - /*! - * Constructs a LogObject pointer that points to the same object then - * \a rOther. The reference counter of the object is incremented by - * one. - */ - LogObjectPtr(const LogObjectPtr &rOther); - - /*! - * Constructs a LogObject pointer that points to the object - * \a LogObject. The reference counter of the object is incremented by - * one. - */ - LogObjectPtr(T *pLogObject); - - /*! - * Assignment operator. Sets the LogObject pointer to point to the - * same object that \a rOther points to. The reference counter of the - * object the LogObjectPtr pointed to before the assignment is - * decremented by one. The reference counter of the object \a rOther - * is pointing to is incremented by one. - */ - LogObjectPtr &operator=(const LogObjectPtr &rOther); - - /*! - * Destructs the object. The reference counter of the object the - * LogObjectPtr points to is decremented by one. - */ - ~LogObjectPtr(); - - /*! - * Assignment operator. Sets the LogObject pointer to point to the - * object \a pLogObject. The reference counter of the object the - * LogObjectPtr pointed to before the assignment is decremented by - * one. The reference counter of the object \a pLogObject is pointing - * to is incremented by one. - */ - LogObjectPtr &operator=(T *pLogObject); - - /*! - * Arrow operator. Returns the LogObject the object points to. - */ - T *operator->() const; - - /*! - * Dereference operator. Returns a pointer to the LogObject the - * object points to. - */ - T &operator*() const; - - /*! - * Cast operator. Cast the object to the LogObject the object points - * to. - */ - operator T*() const; - - private: - void retain() const; - void release() const; - - private: - T *mpLogObject; - }; - - - /************************************************************************** - * Operators, Helper - **************************************************************************/ - - - /************************************************************************** - * Inline - **************************************************************************/ - - template - inline LogObjectPtr::LogObjectPtr() : - mpLogObject(0) - {} - - template - inline LogObjectPtr::LogObjectPtr(const LogObjectPtr &rOther) : - mpLogObject(rOther.mpLogObject) - { retain(); } - - template - inline LogObjectPtr::LogObjectPtr(T *pLogObject) : - mpLogObject(pLogObject) - { retain(); } - - template - inline LogObjectPtr &LogObjectPtr::operator=(const LogObjectPtr &rOther) - { rOther.retain(); - release(); - mpLogObject = rOther.mpLogObject; - return *this; } - - template - inline LogObjectPtr::~LogObjectPtr() - { release(); } - - template - inline LogObjectPtr &LogObjectPtr::operator=(T *pLogObject) - { if (pLogObject) - reinterpret_cast(pLogObject)->retain(); - release(); - mpLogObject = pLogObject; - return *this; } - - template - inline T *LogObjectPtr::operator->() const - { return mpLogObject; } - - template - inline T &LogObjectPtr::operator*() const - { return *mpLogObject; } - - template - inline LogObjectPtr::operator T*() const - { return mpLogObject; } - - template - inline void LogObjectPtr::retain() const - { if (mpLogObject) - reinterpret_cast(mpLogObject)->retain(); } - - template - inline void LogObjectPtr::release() const - { - if (mpLogObject) - reinterpret_cast(mpLogObject)->release(); - } - -} // namespace Log4Qt - - -//Q_DECLARE_TYPEINFO(Log4Qt::LogObjectPtr, Q_MOVABLE_TYPE); // Declare within T - - -#endif // LOG4QT_LOGOBJECTPTR_H diff --git a/src/log4qt/src/log4qt/helpers/optionconverter.cpp b/src/log4qt/src/log4qt/helpers/optionconverter.cpp deleted file mode 100644 index 15fb645..0000000 --- a/src/log4qt/src/log4qt/helpers/optionconverter.cpp +++ /dev/null @@ -1,315 +0,0 @@ -/****************************************************************************** - * - * package: Log4Qt - * file: optionconverter.cpp - * created: September 2007 - * author: Martin Heinrich - * - * - * changes Feb 2009, Martin Heinrich - * - Fixed a problem were OptionConverter::toBoolean would not - * return the default value, if the conversion fails. - * - * - * Copyright 2007 - 2009 Martin Heinrich - * - * 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. - * - ******************************************************************************/ - - -/****************************************************************************** - * Dependencies - ******************************************************************************/ - - -#include "log4qt/helpers/optionconverter.h" - -#include -#include "log4qt/helpers/logerror.h" -#include "log4qt/helpers/properties.h" -#include "log4qt/logger.h" -#include "log4qt/consoleappender.h" - - - -namespace Log4Qt -{ - - - /************************************************************************** - * Declarations - **************************************************************************/ - - - - /************************************************************************** - * C helper functions - **************************************************************************/ - - - LOG4QT_DECLARE_STATIC_LOGGER(logger, Log4Qt::OptionConverter) - - - - /************************************************************************** - * Class implementation: OptionConverter - **************************************************************************/ - - - QString OptionConverter::findAndSubst(const Properties &rProperties, - const QString &rKey) - { - QString value = rProperties.property(rKey); - if (value.isNull()) - return value; - - const QString begin_subst = QLatin1String("${"); - const QString end_subst = QLatin1String("}"); - const int begin_length = begin_subst.length(); - const int end_length = end_subst.length(); - - // Don't return a null string, the null string indicates that the - // property key does not exist. - QString result = QLatin1String(""); - - int i = 0; - int begin; - int end; - while (i < value.length()) - { - begin = value.indexOf(begin_subst, i); - if (begin == -1) - { - result += value.mid(i); - i = value.length(); - } - else - { - result += value.mid(i, begin - i); - end = value.indexOf(end_subst, i + begin_length); - if (end == -1) - { - LogError e = LOG4QT_ERROR(QT_TR_NOOP("Missing closing bracket for opening bracket at %1. Invalid subsitution in value %2."), - CONFIGURATOR_INVALID_SUBSTITUTION_ERROR, - "Log4Qt::OptionConverter"); - e << begin << value; - logger()->error(e); - return result; - } - else - { - result += findAndSubst(rProperties, value.mid(begin + begin_length, end - begin - end_length - 1)); - i = end + end_length; - } - } - } - return result; - } - - - QString OptionConverter::classNameJavaToCpp(const QString &rClassName) - { - const QLatin1String java_class_delimiter("."); - const QLatin1String cpp_class_delimiter("::"); - - QString result = rClassName; - return result.replace(java_class_delimiter, cpp_class_delimiter); - } - - - bool OptionConverter::toBoolean(const QString &rOption, - bool *p_ok) - { - const QLatin1String str_true("true"); - const QLatin1String str_enabled("enabled"); - const QLatin1String str_one("1"); - const QLatin1String str_false("false"); - const QLatin1String str_disabled("disabled"); - const QLatin1String str_zero("0"); - - if (p_ok) - *p_ok = true; - QString s = rOption.trimmed().toLower(); - if (s == str_true || s == str_enabled || s == str_one) - return true; - if (s == str_false || s == str_disabled || s == str_zero) - return false; - - if (p_ok) - *p_ok = false; - LogError e = LOG4QT_ERROR(QT_TR_NOOP("Invalid option string '%1' for a boolean"), - CONFIGURATOR_INVALID_OPTION_ERROR, - "Log4Qt::OptionConverter"); - e << rOption; - logger()->error(e); - return false; - } - - - bool OptionConverter::toBoolean(const QString &rOption, - bool default_value) - { - bool ok; - bool result = toBoolean(rOption, &ok); - if (ok) - return result; - else - return default_value; - } - - qint64 OptionConverter::toFileSize(const QString &rOption, - bool *p_ok) - { - // - Search for unit - // - Convert characters befor unit to int - // - Error, if - // - the conversion failed - // - the value < 0 - // - there is text after the unit characters - - if (p_ok) - *p_ok = false; - QString s = rOption.trimmed().toLower(); - qint64 f = 1; - int i; - i = s.indexOf(QLatin1String("kb")); - if (i >= 0) - f = 1024; - else - { - i = s.indexOf(QLatin1String("mb")); - if (i >= 0) - f = 1024 * 1024; - else - { - i = s.indexOf(QLatin1String("gb")); - if (i >= 0) - f = 1024 * 1024 * 1024; - } - } - if (i < 0) - i = s.length(); - bool ok; - qint64 value = s.left(i).toLongLong(&ok); - if (!ok || value < 0 || s.length() > i + 2) - { - LogError e = LOG4QT_ERROR(QT_TR_NOOP("Invalid option string '%1' for a file size"), - CONFIGURATOR_INVALID_OPTION_ERROR, - "Log4Qt::OptionConverter"); - e << rOption; - logger()->error(e); - return 0; - } - if (p_ok) - *p_ok = true; - return value * f; - } - - - int OptionConverter::toInt(const QString &rOption, - bool *p_ok) - { - int value = rOption.trimmed().toInt(p_ok); - if (*p_ok) - return value; - - LogError e = LOG4QT_ERROR(QT_TR_NOOP("Invalid option string '%1' for an integer"), - CONFIGURATOR_INVALID_OPTION_ERROR, - "Log4Qt::OptionConverter"); - e << rOption; - logger()->error(e); - return 0; - } - - qint64 OptionConverter::toQInt64(const QString &rOption, - bool *p_ok) - { - int value = rOption.trimmed().toLongLong(p_ok); - if (*p_ok) - return value; - - LogError e = LOG4QT_ERROR(QT_TR_NOOP("Invalid option string '%1' for an qint64"), - CONFIGURATOR_INVALID_OPTION_ERROR, - "Log4Qt::OptionConverter"); - e << rOption; - logger()->error(e); - return 0; - } - - Level OptionConverter::toLevel(const QString &rOption, - bool *p_ok) - { - bool ok; - Level level = Level::fromString(rOption.toUpper().trimmed(), &ok); - if (p_ok) - *p_ok = ok; - if (ok) - return level; - - LogError e = LOG4QT_ERROR(QT_TR_NOOP("Invalid option string '%1' for a level"), - CONFIGURATOR_INVALID_OPTION_ERROR, - "Log4Qt::OptionConverter"); - e << rOption; - logger()->error(e); - return level; - } - - - Level OptionConverter::toLevel(const QString &rOption, - const Level &rDefaultValue) - { - bool ok; - Level result = toLevel(rOption, &ok); - if (ok) - return result; - else - return rDefaultValue; - } - - - int OptionConverter::toTarget(const QString &rOption, - bool *p_ok) - { - const QLatin1String java_stdout("system.out"); - const QLatin1String cpp_stdout("stdout_target"); - const QLatin1String java_stderr("system.err"); - const QLatin1String cpp_stderr("stderr_target"); - - if (p_ok) - *p_ok = true; - QString s = rOption.trimmed().toLower(); - if (s == java_stdout || s == cpp_stdout) - return ConsoleAppender::STDOUT_TARGET; - if (s == java_stderr || s == cpp_stderr) - return ConsoleAppender::STDERR_TARGET; - - if (p_ok) - *p_ok = false; - LogError e = LOG4QT_ERROR(QT_TR_NOOP("Invalid option string '%1' for a target"), - CONFIGURATOR_INVALID_OPTION_ERROR, - "Log4Qt::OptionConverter"); - e << rOption; - logger()->error(e); - return ConsoleAppender::STDOUT_TARGET; - } - - - - /************************************************************************** - * Implementation: Operators, Helper - **************************************************************************/ - - - -} // namespace Log4Qt diff --git a/src/log4qt/src/log4qt/helpers/optionconverter.h b/src/log4qt/src/log4qt/helpers/optionconverter.h deleted file mode 100644 index 50027e4..0000000 --- a/src/log4qt/src/log4qt/helpers/optionconverter.h +++ /dev/null @@ -1,150 +0,0 @@ -/****************************************************************************** - * - * package: Log4Qt - * file: optionconverter.h - * created: September 2007 - * author: Martin Heinrich - * - * - * Copyright 2007 Martin Heinrich - * - * 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. - * - ******************************************************************************/ - -#ifndef LOG4QT_OPTIONCONVERTER_H -#define LOG4QT_OPTIONCONVERTER_H - - -/****************************************************************************** - * Dependencies - ******************************************************************************/ - -#include -#include "log4qt/level.h" - -namespace Log4Qt -{ - class Properties; - - /*! - * \brief The class OptionConverter provides functions to convert strings - * to property values. - */ - class OptionConverter - { - private: - OptionConverter(); - OptionConverter(const OptionConverter &rOther); // Not implemented - // virtual ~OptionConverter(); // Use compiler default - OptionConverter &operator=(const OptionConverter &rOther); // Not implemented - - public: - static QString findAndSubst(const Properties &rProperties, - const QString &rKey); - - /*! - * Returns the JAVA class name \a rClassName as C++ class name by - * replacing all . characters with ::. - */ - static QString classNameJavaToCpp(const QString &rClassName); - - /*! - * Converts the option \a rOption to a boolean value. Valid strings - * for true are "true", "enabled" and "1". Valid strings - * for false are "false", "disabled" and "0". If the conversion is - * successful, the target is returned and \a p_ok is set to true. - * Otherwise an error is written to the log, \a p_ok is set to false - * and false is returned. - */ - static bool toBoolean(const QString &rOption, - bool *p_ok = 0); - - static bool toBoolean(const QString &rOption, - bool default_value); - - /*! - * Converts the option string \a rOption to a file size. The string can - * be a positive integer followed by an optional unit suffix "KB", "MB" - * or "GB". If a unit suffix is specified the the integer is - * interpreted as kilobytes, megabytes or gigabytes. If the conversion - * is successful, the size is returned and \a p_ok is set to true. - * Otherwise an error is written to the log, \a p_ok is set to false - * and 0 is returned. - */ - static qint64 toFileSize(const QString &rOption, - bool *p_ok = 0); - - /*! - * Converts the option \a rOption to a integer value using - * QString::toInt(). If the conversion is successful, the integer is - * returned and \a p_ok is set to true. Otherwise an error is written - * to the log, \a p_ok is set to false and 0 is returned. - */ - static int toInt(const QString &rOption, - bool *p_ok = 0); - - /*! - * Converts the option \a rOption to a qint64 value using - * QString::toLongLong(). If the conversion is successful, the qint64 is - * returned and \a p_ok is set to true. Otherwise an error is written - * to the log, \a p_ok is set to false and 0 is returned. - */ - static qint64 toQInt64(const QString &rOption, - bool *p_ok = 0); - - /*! - * Converts the option \a rOption to a level value using - * Level::fromString(). If the conversion is successful, the level - * is returned and \a p_ok is set to true. Otherwise an error is - * written to the log, \a p_ok is set to false and a level with - * the value Level::NULL_INT is returned. - * - * \sa Level::fromString() - */ - static Level toLevel(const QString &rOption, - bool *p_ok = 0); - - static Level toLevel(const QString &rOption, - const Level &rDefaultValue); - - /*! - * Converts the option \a rOption to a ConsoleAppender::Target value. - * Valid strings for \a rOption are "System.out", "STDOUT_TARGET", - * "System.err" and "STDERR_TARGET". If the conversion is successful, - * the target is returned and \a p_ok is set to true. Otherwise an - * error is written to the log, \a p_ok is set to false and - * ConsoleAppender::STDOUT_TARGET is returned. - */ - static int toTarget(const QString &rOption, - bool *p_ok = 0); - }; - - - /************************************************************************** - * Operators, Helper - **************************************************************************/ - - - /************************************************************************** - * Inline - **************************************************************************/ - - -} // namespace Log4Qt - - -Q_DECLARE_TYPEINFO(Log4Qt::OptionConverter, Q_MOVABLE_TYPE); - - -#endif // LOG4QT_OPTIONCONVERTER_H diff --git a/src/log4qt/src/log4qt/helpers/patternformatter.cpp b/src/log4qt/src/log4qt/helpers/patternformatter.cpp deleted file mode 100644 index 60f5271..0000000 --- a/src/log4qt/src/log4qt/helpers/patternformatter.cpp +++ /dev/null @@ -1,893 +0,0 @@ -/****************************************************************************** - * - * package: Log4Qt - * file: patternformatter.cpp - * created: September 2007 - * author: Martin Heinrich - * - * - * changes Feb 2009, Martin Heinrich - * - Fixed VS 2008 unreferenced formal parameter warning by using - * Q_UNUSED in LiteralPatternConverter::convert. - * - * - * Copyright 2007 - 2009 Martin Heinrich - * - * 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. - * - ******************************************************************************/ - - - -/****************************************************************************** - * Dependencies - ******************************************************************************/ - -#include "log4qt/helpers/patternformatter.h" - -#include -#include -#include -#include "log4qt/helpers/datetime.h" -#include "log4qt/helpers/logerror.h" -#include "log4qt/layout.h" -#include "log4qt/logger.h" -#include "log4qt/loggingevent.h" - - - -namespace Log4Qt -{ - - - /************************************************************************** - *Declarations - **************************************************************************/ - - - /*! - * \brief The class FormattingInfo stores the formatting modifier for a - * pattern converter. - * - * \sa PatternConverter - */ - class FormattingInfo - { - public: - FormattingInfo() - { clear(); } - // FormattingInfo(const FormattingInfo &rOther); // Use compiler default - // virtual ~FormattingInfo(); // Use compiler default - // FormattingInfo &operator=(const FormattingInfo &rOther); // Use compiler default - - void clear(); - static QString intToString(int i); - - public: - int mMinLength; - int mMaxLength; - bool mLeftAligned; - }; - - - /*! - * \brief The class PatternConverter is the abstract base class for all - * pattern converters. - * - * PatternConverter handles the minimum and maximum modifier for a - * conversion character. The actual conversion is by calling the - * convert() member function of the derived class. - * - * \sa PatternLayout::format() - */ - class PatternConverter - { - public: - PatternConverter(const FormattingInfo &rFormattingInfo = FormattingInfo()) : - mFormattingInfo(rFormattingInfo) - {}; - virtual ~PatternConverter() - {}; - private: - PatternConverter(const PatternConverter &rOther); // Not implemented - PatternConverter &operator=(const PatternConverter &rOther); // Not implemented - - public: - void format(QString &rFormat, const LoggingEvent &rLoggingEvent) const; - - protected: - virtual QString convert(const LoggingEvent &rLoggingEvent) const = 0; - #ifndef QT_NO_DEBUG_STREAM - virtual QDebug debug(QDebug &rDebug) const = 0; - friend QDebug operator<<(QDebug, const PatternConverter &rPatternConverter); - #endif - - protected: - FormattingInfo mFormattingInfo; - }; - - - /*! - * \brief The class BasicPatternConverter converts several members of a - * LoggingEvent to a string. - * - * BasicPatternConverter is used by PatternLayout to convert members that - * do not reuquire additional formatting to a string as part of formatting - * the LoggingEvent. It handles the following conversion characters: - * 'm', 'p', 't', 'x' - * - * \sa PatternLayout::format() - * \sa PatternConverter::format() - */ - class BasicPatternConverter : public PatternConverter - { - public: - enum Type { - MESSAGE_CONVERTER, - NDC_CONVERTER, - LEVEL_CONVERTER, - THREAD_CONVERTER, - }; - - public: - BasicPatternConverter(const FormattingInfo &rFormattingInfo, - Type type) : - PatternConverter(rFormattingInfo), - mType(type) - {}; - // virtual ~BasicPatternConverter(); // Use compiler default - private: - BasicPatternConverter(const BasicPatternConverter &rOther); // Not implemented - BasicPatternConverter &operator=(const BasicPatternConverter &rOther); // Not implemented - - protected: - virtual QString convert(const LoggingEvent &rLoggingEvent) const; - #ifndef QT_NO_DEBUG_STREAM - virtual QDebug debug(QDebug &rDebug) const; - #endif - - private: - Type mType; - }; - - - /*! - * \brief The class DatePatternConverter converts the time stamp of a - * LoggingEvent to a string. - * - * DatePatternConverter is used by PatternLayout to convert the time stamp - * of a LoggingEvent to a string as part of formatting the LoggingEvent. - * It handles the 'd' and 'r' conversion character. - * - * \sa PatternLayout::format() - * \sa PatternConverter::format() - */ - class DatePatternConverter : public PatternConverter - { - public: - DatePatternConverter(const FormattingInfo &rFormattingInfo, - const QString &rFormat) : - PatternConverter(rFormattingInfo), - mFormat(rFormat) - {}; - // virtual ~DatePatternConverter(); // Use compiler default - private: - DatePatternConverter(const DatePatternConverter &rOther); // Not implemented - DatePatternConverter &operator=(const DatePatternConverter &rOther); // Not implemented - - protected: - virtual QString convert(const LoggingEvent &rLoggingEvent) const; - #ifndef QT_NO_DEBUG_STREAM - virtual QDebug debug(QDebug &rDebug) const; - #endif - - private: - QString mFormat; - }; - - - /*! - * \brief The class LiteralPatternConverter provides string literals. - * - * LiteralPatternConverter is used by PatternLayout to embed string - * literals as part of formatting the LoggingEvent. It handles string - * literals and the 'n' conversion character. - * - * \sa PatternLayout::format() - * \sa PatternConverter::format() - */ - class LiteralPatternConverter : public PatternConverter - { - public: - LiteralPatternConverter(const QString &rLiteral) : - PatternConverter(), - mLiteral(rLiteral) - {}; - // virtual ~LiteralPatternConverter(); // Use compiler default - private: - LiteralPatternConverter(const LiteralPatternConverter &rOther); // Not implemented - LiteralPatternConverter &operator=(const LiteralPatternConverter &rOther); // Not implemented - - protected: - virtual QString convert(const LoggingEvent &rLoggingEvent) const; - #ifndef QT_NO_DEBUG_STREAM - virtual QDebug debug(QDebug &rDebug) const; - #endif - - private: - QString mLiteral; - }; - - - /*! - * \brief The class LoggerPatternConverter converts the Logger name of a - * LoggingEvent to a string. - * - * LoggerPatternConverter is used by PatternLayout to convert the Logger - * name of a LoggingEvent to a string as part of formatting the - * LoggingEvent. It handles the 'c' conversion character. - * - * \sa PatternLayout::format() - * \sa PatternConverter::format() - */ - class LoggerPatternConverter : public PatternConverter - { - public: - LoggerPatternConverter(const FormattingInfo &rFormattingInfo, - int precision) : - PatternConverter(rFormattingInfo), - mPrecision(precision) - {}; - // virtual ~LoggerPatternConverter(); // Use compiler default - private: - LoggerPatternConverter(const LoggerPatternConverter &rOther); // Not implemented - LoggerPatternConverter &operator=(const LoggerPatternConverter &rOther); // Not implemented - - protected: - virtual QString convert(const LoggingEvent &rLoggingEvent) const; - #ifndef QT_NO_DEBUG_STREAM - virtual QDebug debug(QDebug &rDebug) const; - #endif - - private: - int mPrecision; - }; - - - - /*! - * \brief The class MDCPatternConverter converts the MDC data of a - * LoggingEvent to a string. - * - * MDCPatternConverter is used by PatternLayout to convert the MDC data of - * a LoggingEvent to a string as part of formatting the LoggingEvent. It - * handles the 'X' conversion character. - * - * \sa PatternLayout::format() - * \sa PatternConverter::format() - */ - class MDCPatternConverter : public PatternConverter - { - public: - MDCPatternConverter(const FormattingInfo &rFormattingInfo, - const QString &rKey) : - PatternConverter(rFormattingInfo), - mKey(rKey) - {}; - // virtual ~MDCPatternConverter(); // Use compiler default - private: - MDCPatternConverter(const MDCPatternConverter &rOther); // Not implemented - MDCPatternConverter &operator=(const MDCPatternConverter &rOther); // Not implemented - - protected: - virtual QString convert(const LoggingEvent &rLoggingEvent) const; - #ifndef QT_NO_DEBUG_STREAM - virtual QDebug debug(QDebug &rDebug) const; - #endif - - private: - QString mKey; - }; - - - #ifndef QT_NO_DEBUG_STREAM - QDebug operator<<(QDebug, const FormattingInfo &rFormattingInfo); - #endif - - - #ifndef QT_NO_DEBUG_STREAM - QDebug operator<<(QDebug, const PatternConverter &rPatternConverter); - #endif - - - - /************************************************************************** - * C helper functions - **************************************************************************/ - - - LOG4QT_DECLARE_STATIC_LOGGER(logger, Log4Qt::PatternFormatter) - - - - /************************************************************************** - * Class implementation: PatternFormatter - **************************************************************************/ - - - PatternFormatter::PatternFormatter(const QString &rPattern) : - mIgnoreCharacters(QLatin1String("CFlLM")), - mConversionCharacters(QLatin1String("cdmprtxX")), - mOptionCharacters(QLatin1String("cd")), - mPattern(rPattern), - mPatternConverters() - { - parse(); - } - - - PatternFormatter::~PatternFormatter() - { - PatternConverter *p_converter; - Q_FOREACH(p_converter, mPatternConverters) - delete p_converter; - } - - - QString PatternFormatter::format(const LoggingEvent &rLoggingEvent) const - { - QString result; - PatternConverter *p_converter; - Q_FOREACH(p_converter, mPatternConverters) - p_converter->format(result, rLoggingEvent); - return result; - } - - - bool PatternFormatter::addDigit(const QChar &rDigit, - int &rValue) - { - if (!rDigit.isDigit()) - return false; - - int digit_value = rDigit.digitValue(); - if (rValue > (INT_MAX - digit_value) / 10) - rValue = INT_MAX; - else - rValue = rValue * 10 + digit_value; - return true; - } - - - void PatternFormatter::createConverter(const QChar &rChar, - const FormattingInfo &rFormattingInfo, - const QString &rOption) - { - Q_ASSERT_X(mConversionCharacters.indexOf(rChar) >= 0, "PatternFormatter::createConverter", "Unknown conversion character" ); - - LogError e("Creating Converter for character '%1' min %2, max %3, left %4 and option '%5'"); - e << QString(rChar) - << FormattingInfo::intToString(rFormattingInfo.mMinLength) - << FormattingInfo::intToString(rFormattingInfo.mMaxLength) - << rFormattingInfo.mLeftAligned - << rOption; - logger()->trace(e); - - switch (rChar.toLatin1()) - { - case 'c': - mPatternConverters << new LoggerPatternConverter(rFormattingInfo, - parseIntegerOption(rOption)); - break; - case 'd': - { - QString option = rOption; - if (rOption.isEmpty()) - option = QLatin1String("ISO8601"); - mPatternConverters << new DatePatternConverter(rFormattingInfo, - option); - break; - } - case 'm': - mPatternConverters << new BasicPatternConverter(rFormattingInfo, - BasicPatternConverter::MESSAGE_CONVERTER); - break; - case 'p': - mPatternConverters << new BasicPatternConverter(rFormattingInfo, - BasicPatternConverter::LEVEL_CONVERTER); - break; - case 'r': - mPatternConverters << new DatePatternConverter(rFormattingInfo, - QLatin1String("TIME_RELATIVE")); - break; - case 't': - mPatternConverters << new BasicPatternConverter(rFormattingInfo, - BasicPatternConverter::THREAD_CONVERTER); - break; - case 'x': - mPatternConverters << new BasicPatternConverter(rFormattingInfo, - BasicPatternConverter::NDC_CONVERTER); - break; - case 'X': - mPatternConverters << new MDCPatternConverter(rFormattingInfo, - rOption); - break; - default: - Q_ASSERT_X(false, "PatternFormatter::createConverter", "Unknown pattern character"); - } - } - - - void PatternFormatter::createLiteralConverter(const QString &rLiteral) - { - logger()->trace("Creating literal LiteralConverter with Literal '%1'", - rLiteral); - mPatternConverters << new LiteralPatternConverter(rLiteral); - } - - - void PatternFormatter::parse() - { - enum State { - LITERAL_STATE, - ESCAPE_STATE, - MIN_STATE, - DOT_STATE, - MAX_STATE, - CHARACTER_STATE, - POSSIBLEOPTION_STATE, - OPTION_STATE - }; - - int i = 0; - QChar c; - char ch; - State state = LITERAL_STATE; - FormattingInfo formatting_info; - QString literal; - int converter_start; - int option_start; - while (i < mPattern.length()) - { - // i points to the current character - // c contains the current character - // ch contains the Latin1 equivalent of the current character - // i is incremented at the end of the loop to consume the character - // continue is used to change state without consuming the character - - c = mPattern.at(i); - ch = c.toLatin1(); - switch (state) - { - case LITERAL_STATE: - if (ch == '%') - { - formatting_info.clear(); - converter_start = i; - state = ESCAPE_STATE; - } else - literal += c; - break; - case ESCAPE_STATE: - if (ch == '%') - { - literal += c; - state = LITERAL_STATE; - } - else if (ch == 'n') - { - literal += Layout::endOfLine(); - state = LITERAL_STATE; - } - else - { - if (!literal.isEmpty()) - { - createLiteralConverter(literal); - literal.clear(); - } - if (ch == '-') - formatting_info.mLeftAligned = true; - else if (c.isDigit()) - { - formatting_info.mMinLength = c.digitValue(); - state = MIN_STATE; - } - else if (ch == '.') - state = DOT_STATE; - else - { - state = CHARACTER_STATE; - continue; - } - } - break; - case MIN_STATE: - if (!addDigit(c, formatting_info.mMinLength)) - { - if (ch == '.') - state = DOT_STATE; - else - { - state = CHARACTER_STATE; - continue; - } - } - break; - case DOT_STATE: - if (c.isDigit()) - { - formatting_info.mMaxLength = c.digitValue(); - state = MAX_STATE; - } - else - { - LogError e = LOG4QT_ERROR(QT_TR_NOOP("Found character '%1' where digit was expected."), - LAYOUT_EXPECTED_DIGIT_ERROR, - "Log4Qt::PatternFormatter"); - e << QString(c); - logger()->error(e); - } - break; - case MAX_STATE: - if (!addDigit(c, formatting_info.mMaxLength)) - { - state = CHARACTER_STATE; - continue; - } - break; - case CHARACTER_STATE: - if (mIgnoreCharacters.indexOf(c) >= 0) - state = LITERAL_STATE; - else if (mOptionCharacters.indexOf(c) >= 0) - state = POSSIBLEOPTION_STATE; - else if (mConversionCharacters.indexOf(c) >= 0) - { - createConverter(c, formatting_info); - state = LITERAL_STATE; - } - else - { - logger()->warn("Invalid conversion character '%1' at %2 in pattern '%3'", - c, i, mPattern); - createLiteralConverter(mPattern.mid(converter_start, i - converter_start + 1)); - state = LITERAL_STATE; - } - break; - case POSSIBLEOPTION_STATE: - if (ch == '{') - { - option_start = i; - state = OPTION_STATE; - } - else - { - createConverter(mPattern.at(i - 1), - formatting_info); - state = LITERAL_STATE; - continue; - } - break; - case OPTION_STATE: - if (ch == '}') - { - createConverter(mPattern.at(option_start - 1), - formatting_info, - mPattern.mid(option_start + 1, i - option_start - 1)); - state = LITERAL_STATE; - } - break; - default: - Q_ASSERT_X(false, "PatternFormatter::parse()", "Unknown parsing state constant"); - state = LITERAL_STATE; - } - i++; - } - - if (state != LITERAL_STATE) - { - logger()->warn("Unexptected end of pattern '%1'", mPattern); - if (state == ESCAPE_STATE) - literal += c; - else - literal += mPattern.mid(converter_start); - } - - if (!literal.isEmpty()) - createLiteralConverter(literal); - } - - - int PatternFormatter::parseIntegerOption(const QString &rOption) - { - if (rOption.isEmpty()) - return 0; - - bool ok; - int result = rOption.toInt(&ok); - if (!ok) - { - LogError e = LOG4QT_ERROR(QT_TR_NOOP("Option '%1' cannot be converted into an integer"), - LAYOUT_OPTION_IS_NOT_INTEGER_ERROR, - "Log4Qt::PatterFormatter"); - e << rOption; - logger()->error(e); - } - if (result < 0) - { - LogError e = LOG4QT_ERROR(QT_TR_NOOP("Option %1 isn't a positive integer"), - LAYOUT_INTEGER_IS_NOT_POSITIVE_ERROR, - "Log4Qt::PatterFormatter"); - e << result; - logger()->error(e); - result = 0; - } - return result; - } - - - /************************************************************************** - * Class implementation: FormattingInfo - **************************************************************************/ - - - void FormattingInfo::clear() - { - mMinLength = 0; - mMaxLength = INT_MAX; - mLeftAligned = false; - }; - - - QString FormattingInfo::intToString(int i) - { - if (i == INT_MAX) - return QLatin1String("INT_MAX"); - else - return QString::number(i); - } - - - - /************************************************************************** - * Class implementation: PatternConverter - **************************************************************************/ - - - void PatternConverter::format(QString &rFormat, const LoggingEvent &rLoggingEvent) const - { - const QLatin1Char space(' '); - QString s = convert(rLoggingEvent); - - if (s.length() > mFormattingInfo.mMaxLength) - rFormat += s.left(mFormattingInfo.mMaxLength); - else if (mFormattingInfo.mLeftAligned) - rFormat += s.leftJustified(mFormattingInfo.mMinLength, space, false); - else - rFormat += s.rightJustified(mFormattingInfo.mMinLength, space, false); - } - - - - /************************************************************************** - * Class implementation: BasicPatternConverter - **************************************************************************/ - - - QString BasicPatternConverter::convert(const LoggingEvent &rLoggingEvent) const - { - switch (mType) - { - case MESSAGE_CONVERTER: - return rLoggingEvent.message(); - break; - case NDC_CONVERTER: - return rLoggingEvent.ndc(); - break; - case LEVEL_CONVERTER: - return rLoggingEvent.level().toString(); - break; - case THREAD_CONVERTER: - return rLoggingEvent.threadName(); - break; - default: - Q_ASSERT_X(false, "BasicPatternConverter::convert()", "Unkown type constant"); - return QString(); - } - } - - - QDebug BasicPatternConverter::debug(QDebug &rDebug) const - { - QString type; - switch (mType) - { - case MESSAGE_CONVERTER: - type = QLatin1String("MESSAGE_CONVERTER"); - break; - case NDC_CONVERTER: - type = QLatin1String("NDC_CONVERTER"); - break; - case LEVEL_CONVERTER: - type = QLatin1String("LEVEL_CONVERTER"); - break; - case THREAD_CONVERTER: - type = QLatin1String("THREAD_CONVERTER"); - break; - default: - Q_ASSERT_X(false, "BasicPatternConverter::debug()", "Unkown type constant"); - } - rDebug.nospace() << "BasicPatternConverter(" - << mFormattingInfo - << "type:" << type - << ")"; - return rDebug.space(); - } - - - - /************************************************************************** - * Class implementation: DatePatternConverter - **************************************************************************/ - - - QString DatePatternConverter::convert(const LoggingEvent &rLoggingEvent) const - { - return DateTime::fromMilliSeconds(rLoggingEvent.timeStamp()).toString(mFormat); - } - - - QDebug DatePatternConverter::debug(QDebug &rDebug) const - { - rDebug.nospace() << "DatePatternConverter(" - << mFormattingInfo - << "format:" << mFormat - << ")"; - return rDebug.space(); - } - - - - /************************************************************************** - * Class implementation: LiteralPatternConverter - **************************************************************************/ - - - QString LiteralPatternConverter::convert(const LoggingEvent &rLoggingEvent) const - { - Q_UNUSED(rLoggingEvent); - return mLiteral; - }; - - - QDebug LiteralPatternConverter::debug(QDebug &rDebug) const - { - rDebug.nospace() << "LiteralPatternConverter(" - << mFormattingInfo - << "literal:" << mLiteral - << ")"; - return rDebug.space(); - } - - - - /************************************************************************** - * Class implementation: LoggerPatternConverter - **************************************************************************/ - - - QString LoggerPatternConverter::convert(const LoggingEvent &rLoggingEvent) const - { - if (!rLoggingEvent.logger()) - return QString(); - QString name = rLoggingEvent.logger()->name(); - if (mPrecision <= 0 || (name.isEmpty())) - return name; - - const QString separator(QLatin1String("::")); - - int i = mPrecision; - int begin = name.length(); - while ((i > 0) && (begin >= 0)) - { - begin = name.lastIndexOf(separator, begin - name.length() - 1); - i--; - } - if (begin < 0) - begin = 0; - else - begin += 2; - return name.mid(begin); - } - - - QDebug LoggerPatternConverter::debug(QDebug &rDebug) const - { - rDebug.nospace() << "LoggerPatternConverter(" - << mFormattingInfo - << "precision:" << mPrecision - << ")"; - return rDebug.space(); - } - - - - /****************************************************************************** - * Class implementation: MDCPatternConverter - ******************************************************************************/ - - - QString MDCPatternConverter::convert(const LoggingEvent &rLoggingEvent) const - { - return rLoggingEvent.mdc().value(mKey); - }; - - - QDebug MDCPatternConverter::debug(QDebug &rDebug) const - { - rDebug.nospace() << "MDCPatternConverter(" - << mFormattingInfo - << "key:" << mKey - << ")"; - return rDebug.space(); - } - - - - /************************************************************************** - * Implementation: Operators, Helper - **************************************************************************/ - - - #ifndef QT_NO_DEBUG_STREAM - QDebug operator<<(QDebug debug, const PatternFormatter &rPatternFormatter) - { - debug.nospace() << "PatternFormatter(" - << "pattern:" << rPatternFormatter.mPattern << " " - << "converters:("; - int i; - for (i = 0; i < rPatternFormatter.mPatternConverters.size(); i++) - { - if (i > 0) - debug.nospace() << ", "; - debug.nospace() << *rPatternFormatter.mPatternConverters.at(i); - } - debug.nospace() << ") )"; - return debug.space(); - } - #endif - - -#ifndef QT_NO_DEBUG_STREAM - QDebug operator<<(QDebug debug, const FormattingInfo &rFormattingInfo) - { - debug.nospace() << "FormattingInfo(" - << "min:" << FormattingInfo::intToString(rFormattingInfo.mMinLength) << " " - << "max:" << FormattingInfo::intToString(rFormattingInfo.mMaxLength) << " " - << "left:" << rFormattingInfo.mLeftAligned - << ")"; - return debug.space(); - } -#endif // QT_NO_DEBUG_STREAM - - -#ifndef QT_NO_DEBUG_STREAM - QDebug operator<<(QDebug debug, const PatternConverter &rPatternConverter) - { - return rPatternConverter.debug(debug); - } -#endif // QT_NO_DEBUG_STREAM - - - -} // namespace Log4Qt diff --git a/src/log4qt/src/log4qt/helpers/patternformatter.h b/src/log4qt/src/log4qt/helpers/patternformatter.h deleted file mode 100644 index d5c2898..0000000 --- a/src/log4qt/src/log4qt/helpers/patternformatter.h +++ /dev/null @@ -1,195 +0,0 @@ -/****************************************************************************** - * - * package: Log4Qt - * file: patternformatter.h - * created: September 2007 - * author: Martin Heinrich - * - * - * Copyright 2007 Martin Heinrich - * - * 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. - * - ******************************************************************************/ - -#ifndef LOG4QT_PATTERNFORMATTER_H -#define LOG4QT_PATTERNFORMATTER_H - - -/****************************************************************************** - * Dependencies - ******************************************************************************/ - -#include -#include - - -/****************************************************************************** - * Declarations - ******************************************************************************/ - - -namespace Log4Qt -{ - - class FormattingInfo; - class PatternConverter; - class LoggingEvent; - - /*! - * \brief The class PatternFormatter formats a logging event based on a - * pattern string. - * - * The class PatternFormatter formats a LoggingEvent base on a pattern - * string. It is used by the patternLayout and TTCCLayout class to - * implement the formatting. - * - * On object construction the provided patterns tring is parsed. Based on - * the information found a chain of PatternConverter is created. Each - * PatternConverter handles a certain member of a LoggingEvent. - * - * \sa PatternLayout::format() - * \sa TTCCLayout::format() - */ - class PatternFormatter - { - public: - /*! - * Creates a PatternFormatter using a the specified \a rPattern. - */ - PatternFormatter(const QString &rPattern); - - /*! - * Destroys the PatternFormatter and all PatternConverter. - */ - virtual ~PatternFormatter(); - - private: - PatternFormatter(const PatternFormatter &rOther); // Not implemented - PatternFormatter &operator=(const PatternFormatter &rOther); // Not implemented - - public: - /*! - * Formats the given \a rLoggingEvent using the chain of - * PatternConverter created during construction from the specified - * pattern. - */ - QString format(const LoggingEvent &rLoggingEvent) const; - - private: - /*! - * If the character \a rDigit is a digit the digit is added to the - * integer \a rValue and the function returns true. Otherwise the - * function returns false. - * - * The function adds the digit by multiplying the existing value - * with ten and adding the numerical value of the digit. If the - * maximum integer value would be exceeded by the operation - * \a rValue is set to INT_MAX. - */ - bool addDigit(const QChar &rDigit, - int &rValue); - - /*! - * Creates a PatternConverter based on the specified conversion - * character \a rChar, the formatting information - * \a rFormattingInfo and the option \a rOption. - * - * The PatternConverter converter is appended to the list of - * PatternConverters. - */ - void createConverter(const QChar &rChar, - const FormattingInfo &rFormattingInfo, - const QString &rOption = QString()); - - /*! - * Creates a LiteralPatternConverter with the string literal - * \a rLiteral. - * - * The PatternConverter converter is appended to the list of - * PatternConverters. - */ - void createLiteralConverter(const QString &rLiteral); - - /*! - * Parses the pattern string specified on construction and creates - * PatternConverter according to it. - */ - void parse(); - - /*! - * Parses an integer option from an option string. If the string is - * not a valid integer or the integer value is less then zero, zero - * is returned. Returns the end of line seperator for the operating - * system. - */ - int parseIntegerOption(const QString &rOption); - - private: - const QString mIgnoreCharacters; - const QString mConversionCharacters; - const QString mOptionCharacters; - QString mPattern; - QList mPatternConverters; - - // Needs to be friend to access internal data - friend QDebug operator<<(QDebug, const PatternFormatter &rPatternFormatter); - }; - - - /************************************************************************** - * Operators, Helper - **************************************************************************/ - -#ifndef QT_NO_DEBUG_STREAM - /*! - * \relates PatternFormatter - * - * Writes all object member variables to the given debug stream \a rDebug and - * returns the stream. - * - * - * %PatternFormatter(pattern:"%r [%t] %p %c %x - %m%n" - * converters:( - * DatePatternConverter(FormattingInfo(min:"0" max:"INT_MAX" left:false) format: "TIME_RELATIVE" ) , - * LiteralPatternConverter(FormattingInfo(min:"0" max:"INT_MAX" left:false) literal: " [" ) , - * BasicPatternConverter(FormattingInfo(min:"0" max:"INT_MAX" left:false) type: "THREAD_CONVERTER" ) , - * LiteralPatternConverter(FormattingInfo(min:"0" max:"INT_MAX" left:false) literal: "] " ) , - * BasicPatternConverter(FormattingInfo(min:"0" max:"INT_MAX" left:false) type: "LEVEL_CONVERTER" ) , - * LiteralPatternConverter(FormattingInfo(min:"0" max:"INT_MAX" left:false) literal: " " ) , - * LoggerPatternConverter(FormattingInfo(min:"0" max:"INT_MAX" left:false) precision: 0 ) , - * LiteralPatternConverter(FormattingInfo(min:"0" max:"INT_MAX" left:false) literal: " " ) , - * BasicPatternConverter(FormattingInfo(min:"0" max:"INT_MAX" left:false) type: "NDC_CONVERTER" ) , - * LiteralPatternConverter(FormattingInfo(min:"0" max:"INT_MAX" left:false) literal: " - " ) , - * BasicPatternConverter(FormattingInfo(min:"0" max:"INT_MAX" left:false) type: "MESSAGE_CONVERTER" ) , - * LiteralPatternConverter(FormattingInfo(min:"0" max:"INT_MAX" left:false) literal: "" ) ) ) - * - * \sa QDebug - */ - QDebug operator<<(QDebug debug, - const PatternFormatter &rPatternFormatter); -#endif // QT_NO_DEBUG_STREAM - - - /************************************************************************** - * Inline - **************************************************************************/ - - -} // namespace Log4Qt - - -Q_DECLARE_TYPEINFO(Log4Qt::PatternFormatter, Q_MOVABLE_TYPE); - - -#endif // LOG4QT_PATTERNFORMATTER_H diff --git a/src/log4qt/src/log4qt/helpers/properties.cpp b/src/log4qt/src/log4qt/helpers/properties.cpp deleted file mode 100644 index 96d04d7..0000000 --- a/src/log4qt/src/log4qt/helpers/properties.cpp +++ /dev/null @@ -1,364 +0,0 @@ -/****************************************************************************** - * - * package: Log4Qt - * file: properties.cpp - * created: September 2007 - * author: Martin Heinrich - * - * - * Copyright 2007 Martin Heinrich - * - * 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. - * - ******************************************************************************/ - - - -/****************************************************************************** - * Dependencies - ******************************************************************************/ - - -#include "log4qt/helpers/properties.h" - -#include -#include -#include -#include -#include "log4qt/logger.h" - - - -namespace Log4Qt -{ - - - - /************************************************************************** - *Declarations - **************************************************************************/ - - - - /************************************************************************** - * C helper functions - **************************************************************************/ - - - LOG4QT_DECLARE_STATIC_LOGGER(logger, Log4Qt::Properties) - - - - /************************************************************************** - * Class implementation: Properties - **************************************************************************/ - - - void Properties::load(QIODevice *pDevice) - { - const QLatin1Char append_char(msEscapeChar); - - if (!pDevice) - { - logger()->warn("No device specified for load."); - return; - } - - QTextStream stream(pDevice); - QString line; - int line_number = 0; - QString property; - int property_start_line = 1; - - do { - line = trimLeft(stream.readLine()); - line_number++; - - if (!line.isEmpty() && line.at(line.length() - 1) == append_char) - property += line.left(line.length() - 1); - else - { - property += line; - parseProperty(property, property_start_line); - property.clear(); - property_start_line = line_number + 1; - } - } - while (!line.isNull()); - } - - - void Properties::load(const QSettings &rSettings) - { - QStringList keys = rSettings.childKeys(); - QString key; - Q_FOREACH(key, keys) - insert(key, rSettings.value(key).toString()); - } - - - QString Properties::property(const QString &rKey) const - { - // Null string indicates the property does not contain the key. - - if (contains(rKey)) - { - QString value = this->value(rKey); - if (value.isNull()) - return QString(QLatin1String("")); - else - return value; - } - - if (mpDefaultProperties) - return mpDefaultProperties->property(rKey); - else - return QString(); - } - - - QString Properties::property(const QString &rKey, - const QString &rDefaultValue) const - { - QString value = property(rKey); - if (value.isNull()) - return rDefaultValue; - else - return value; - } - - - QStringList Properties::propertyNames() const - { - QStringList default_keys; - if (mpDefaultProperties) - default_keys = mpDefaultProperties->propertyNames(); - - QStringList keys = this->keys(); - QString key; - Q_FOREACH(key, default_keys) - if (!keys.contains(key)) - keys << key; - - return keys; - } - - - void Properties::parseProperty(const QString &rProperty, - int line) - { - Q_ASSERT_X(rProperty == trimLeft(rProperty), "parseProperty()", "rProperty has leading spaces"); - - enum State - { - KEY_STATE, - KEYSPACE_STATE, - SPACEVALUE_STATE, - VALUE_STATE, - KEYESCAPE_STATE, - VALUEESCAPE_STATE, - UNICODEESCAPE_STATE - }; - const QString value_escape_codes =QLatin1String(msValueEscapeCodes); - const QString value_escape_chars = QLatin1String(msValueEscapeChars); - Q_ASSERT_X(value_escape_codes.length() == value_escape_chars.length(), "parseProperty()", "Value escape sequence character definition does not map"); - const QString key_escape_codes = QLatin1String(msKeyEscapeCodes); - const QString key_escape_chars = QLatin1String(msKeyEscapeChars); - Q_ASSERT_X(key_escape_codes.length() == key_escape_chars.length(), "parseProperty()", "Key escape sequence character definition does not map"); - - if (rProperty.isEmpty()) - return; - - int i = 0; - QChar c; - char ch; - State state = KEY_STATE; - QString key; - QString value; - QString *p_string = &key; - uint ucs; - int ucs_digits; - while (i < rProperty.length()) - { - // i points to the current character. - // c contains the current character - // ch contains the Latin1 equivalent of the current character - // i is incremented at the end of the loop to consume the character. - // continue is used to change state without consuming the character - - c = rProperty.at(i); - ch = c.toLatin1(); - - switch (state) - { - case KEY_STATE: - if (ch == '!' || ch == '#' ) - return; - else if (c.isSpace()) - { - p_string = &value; - state = KEYSPACE_STATE; - } - else if (ch == '=' || ch == ':') - { - p_string = &value; - state = SPACEVALUE_STATE; - } - else if (ch == msEscapeChar) - state = KEYESCAPE_STATE; - else - *p_string += c; - break; - case KEYSPACE_STATE: - if (ch == '=' || ch == ':') - state = SPACEVALUE_STATE; - else if (!c.isSpace()) - { - *p_string += c; - state = VALUE_STATE; - } - break; - case SPACEVALUE_STATE: - if (!c.isSpace()) - { - *p_string += c; - state = VALUE_STATE; - } - break; - case VALUE_STATE: - if (ch == msEscapeChar) - state = VALUEESCAPE_STATE; - else - *p_string += c; - break; - case KEYESCAPE_STATE: - { - int convert = key_escape_codes.indexOf(c); - if (convert >= 0) - *p_string += key_escape_chars.at(convert); - else - { - logger()->warn("Unknown escape sequence '\\%1' in key of property starting at line %2", - QString(c), - line); - *p_string += c; - } - state = KEY_STATE; - break; - } - case VALUEESCAPE_STATE: - { - int convert = value_escape_codes.indexOf(c); - if (convert >= 0) - { - *p_string += value_escape_chars.at(convert); - state = VALUE_STATE; - } - else if (ch == 'u') - { - ucs = 0; - ucs_digits = 0; - state = UNICODEESCAPE_STATE; - } - else - { - logger()->warn("Unknown escape sequence '\\%1' in value of property starting at line %2", QString(c), line); - *p_string += c; - state = VALUE_STATE; - } - break; - } - case UNICODEESCAPE_STATE: - { - int hex = hexDigitValue(c); - if (hex >= 0) - { - ucs = ucs * 16 + hex; - ucs_digits++; - if (ucs_digits == 4 || i == rProperty.length() - 1) - { - *p_string += QChar(ucs); - state = VALUE_STATE; - } - } - else - { - if (ucs_digits > 0) - *p_string += QChar(ucs); - state = VALUE_STATE; - continue; - } - break; - } - default: - Q_ASSERT_X(false, "Properties::parseProperty()", "Unknown state constant"); - return; - } - i++; - } - - if (key.isEmpty() && !value.isEmpty()) - logger()->warn("Found value with no key in property starting at line %1", line); - - logger()->trace("Loaded property '%1' : '%2'", key, value); - insert(key, value); - } - - - int Properties::hexDigitValue(const QChar &rDigit) - { - bool ok; - int result = QString(rDigit).toInt(&ok, 16); - if (!ok) - return -1; - else - return result; - } - - - QString Properties::trimLeft(const QString &rLine) - { - int i = 0; - while (i < rLine.length() && rLine.at(i).isSpace()) - i++; - return rLine.right(rLine.length() - i); - } - - - const char Properties::msEscapeChar ='\\'; - const char *Properties::msValueEscapeCodes = "tnr\\\"\' "; - const char *Properties::msValueEscapeChars = "\t\n\r\\\"\' "; - const char *Properties::msKeyEscapeCodes = " :="; - const char *Properties::msKeyEscapeChars = " :="; - - - - /************************************************************************** - * Implementation: Operators, Helper - **************************************************************************/ - - -#ifndef QT_NO_DEBUG_STREAM - QDebug operator<<(QDebug debug, const Properties &rProperties) - { - debug.nospace() << "Properties(" - << "default:" << rProperties.defaultProperties() << " " - << "properties:" << *reinterpret_cast *>(&rProperties) - << ")"; - return debug.space(); - } -#endif - - - -} // namespace Log4Qt diff --git a/src/log4qt/src/log4qt/helpers/properties.h b/src/log4qt/src/log4qt/helpers/properties.h deleted file mode 100644 index a9601f4..0000000 --- a/src/log4qt/src/log4qt/helpers/properties.h +++ /dev/null @@ -1,161 +0,0 @@ -/****************************************************************************** - * - * package: Log4Qt - * file: properties.h - * created: September - * author: Martin Heinrich - * - * - * Copyright 2007 Martin Heinrich - * - * 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. - * - ******************************************************************************/ - -#ifndef LOG4QT_PROPERTIES_H -#define LOG4QT_PROPERTIES_H - - -/****************************************************************************** - * Dependencies - ******************************************************************************/ - -#include -#include - - -/****************************************************************************** - * Declarations - ******************************************************************************/ - -class QIODevice; -class QSettings; - - -namespace Log4Qt -{ - /*! - * \brief The class Properties implements a JAVA property hash. - */ - class Properties : public QHash - { - public: - Properties(Properties *pDefaultProperties = 0); - // virtual ~Properties(); // Use compiler default - // Properties(const Properties &rOther); // Use compiler default - // Properties &operator=(const Properties &rOther); // Not implemented - - public: - Properties *defaultProperties() const; - QString property(const QString &rKey) const; - QString property(const QString &rKey, - const QString &rDefaultValue) const; - void setDefaultProperties(Properties *pDefault); - void setProperty(const QString &rKey, - const QString &rValue); - - // JAVA: void list(QTextStream &rTextStream); - void load(QIODevice *pDevice); - - /*! - * Reads all child keys from the QSettings object \a rSettings and - * inserts them into this object. The value is created using - * QVariant::toString(). Types that do not support toString() are - * resulting in an empty string. - * - * \code - * QSettings settings; - * settings.setValue("Package", "Full"); - * settings.setValue("Background", Qt::white); - * settings.setValue("Support", true); - * settings.setValue("Help/Language", "en_UK"); - * - * Properties properties - * properties.load(&settings) - * - * // properties (("Package", "Full"), ("Background", ""), ("Support", "true")) - * \endcode - */ - void load(const QSettings &rSettings); - - QStringList propertyNames() const; - // JAVA: void save(QIODevice *pDevice) const; - - private: - void parseProperty(const QString &rProperty, - int line); - static int hexDigitValue(const QChar &rDigit); - static QString trimLeft(const QString &rString); - - private: - Properties *mpDefaultProperties; - static const char msEscapeChar; - static const char *msValueEscapeCodes; - static const char *msValueEscapeChars; - static const char *msKeyEscapeCodes; - static const char *msKeyEscapeChars; - }; - - - /************************************************************************** - * Operators, Helper - **************************************************************************/ - -#ifndef QT_NO_DEBUG_STREAM - /*! - * \relates Properties - * - * Writes all object member variables to the given debug stream \a rDebug and - * returns the stream. - * - * - * %Properties(default:0x0 properties:QHash(("log4j.appender.testAppender.layout", "org.apache.log4j.PatternLayout ") - * ("log4j.appender.testAppender.layout.ConversionPattern", "[%t] %-5p %l: %m%n") - * ("log4j.appender.testAppender.Append", "false ") - * ("log4j.appender.testAppender.File", "output/temp ") - * ("log4j.rootCategory", "TRACE, testAppender") - * ("log4j.appender.testAppender", "org.apache.log4j.FileAppender")) ) - * - * \sa QDebug - */ - QDebug operator<<(QDebug debug, - const Properties &rProperties); -#endif // QT_NO_DEBUG_STREAM - - - /************************************************************************** - * Inline - **************************************************************************/ - - inline Properties::Properties(Properties *pDefaultProperties) : - mpDefaultProperties(pDefaultProperties) - {} - - inline Properties *Properties::defaultProperties() const - { return mpDefaultProperties; } - - inline void Properties::setDefaultProperties(Properties *pDefaultProperties) - { mpDefaultProperties = pDefaultProperties; } - - inline void Properties::setProperty(const QString &rKey, - const QString &rValue) - { insert(rKey, rValue); } - - -} // namespace Log4Qt - - -Q_DECLARE_TYPEINFO(Log4Qt::Properties, Q_MOVABLE_TYPE); - - -#endif // LOG4QT_PROPERTIES_H diff --git a/src/log4qt/src/log4qt/hierarchy.cpp b/src/log4qt/src/log4qt/hierarchy.cpp deleted file mode 100644 index 283c7fd..0000000 --- a/src/log4qt/src/log4qt/hierarchy.cpp +++ /dev/null @@ -1,212 +0,0 @@ -/****************************************************************************** - * - * package: Log4Qt - * file: hierarchy.cpp - * created: September 2007 - * author: Martin Heinrich - * - * - * changes: Sep 2008, Martin Heinrich: - * - Fixed problem in Qt 4.4 where QReadWriteLock is by default - * non-recursive. - * - * - * Copyright 2007 - 2008 Martin Heinrich - * - * 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. - * - ******************************************************************************/ - - - -/****************************************************************************** - * Dependencies - ******************************************************************************/ - - -#include "log4qt/hierarchy.h" - -#include -#include "log4qt/logger.h" - - - -namespace Log4Qt -{ - - - /************************************************************************** - * Declarations - **************************************************************************/ - - - - /************************************************************************** - * C helper functions - **************************************************************************/ - - - LOG4QT_DECLARE_STATIC_LOGGER(static_logger, Log4Qt::LoggerRepository) - - - - /************************************************************************** - * Class implementation: Hierarchy - **************************************************************************/ - - - Hierarchy::Hierarchy() : -#if QT_VERSION < QT_VERSION_CHECK(4, 4, 0) - mObjectGuard(), -#else - mObjectGuard(QReadWriteLock::Recursive), -#endif - mLoggers(), - mThreshold(Level::NULL_INT), - mpRootLogger(logger(QString())) - { - // Store root logger to allow rootLogger() to be const - } - - - Hierarchy::~Hierarchy() - { - static_logger()->warn("Unexpected destruction of Hierarchy"); - - // QWriteLocker locker(&mObjectGuard); - // - // resetConfiguration(); - // clear(); - // delete mpRootLogger; - } - - - bool Hierarchy::exists(const QString &rName) const - { - QReadLocker locker(&mObjectGuard); - - return mLoggers.contains(rName); - } - - - Logger *Hierarchy::logger(const QString &rName) - { - QWriteLocker locker(&mObjectGuard); - - return createLogger(rName); - } - - - QList Hierarchy::loggers() const - { - QReadLocker locker(&mObjectGuard); - - return mLoggers.values(); - } - - - void Hierarchy::setThreshold(const QString &rThreshold) - { - setThreshold(Level::fromString(rThreshold)); - } - - - void Hierarchy::resetConfiguration() - { - QWriteLocker locker(&mObjectGuard); - - // Reset all loggers. - // Leave log, qt and root logger to the last to allow debugging of shutdown. - - Logger *p_logging_logger = logger(QLatin1String("Log4Qt")); - Logger *p_qt_logger = logger(QLatin1String("Qt")); - Logger *p_root_logger = rootLogger(); - - Logger *p_logger; - Q_FOREACH(p_logger, mLoggers) - { - if ((p_logger == p_logging_logger) || (p_logger == p_qt_logger) || (p_logger == p_root_logger)) - continue; - resetLogger(p_logger, Level::NULL_INT); - } - resetLogger(p_qt_logger, Level::NULL_INT); - resetLogger(p_logging_logger, Level::NULL_INT); - resetLogger(p_root_logger, Level::DEBUG_INT); - } - - - void Hierarchy::shutdown() - { - static_logger()->debug("Shutting down Hierarchy"); - resetConfiguration(); - } - - -#ifndef QT_NO_DEBUG_STREAM - QDebug Hierarchy::debug(QDebug &rDebug) const - { - rDebug.nospace() << "Hierarchy(" - << "loggers:" << loggers().count() << " " - << "threshold:" << threshold().toString() << " " - << "root-level:" << rootLogger()->level().toString() << " " - << "root-appenders:" << rootLogger()->appenders().count() - << ")"; - return rDebug.space(); - } -#endif // QT_NO_DEBUG_STREAM - - - Logger *Hierarchy::createLogger(const QString &rName) - { - // Q_ASSERT_X(, "Hierarchy::createLogger", "Lock must be held by caller") - - const QString name_separator = QLatin1String("::"); - - Logger *p_logger = mLoggers.value(rName, 0); - if (p_logger != 0) - return p_logger; - - if (rName.isEmpty()) - { - p_logger = new Logger(this, Level::DEBUG_INT, QLatin1String("root"), 0); - mLoggers.insert(QString(), p_logger); - return p_logger; - } - QString parent_name; - int index = rName.lastIndexOf(name_separator); - if (index >=0) - parent_name = rName.left(index); - p_logger = new Logger(this, Level::NULL_INT, rName, createLogger(parent_name)); - mLoggers.insert(rName, p_logger); - return p_logger; - } - - - void Hierarchy::resetLogger(Logger *pLogger, Level level) const - { - // Q_ASSERT_X(, "Hierarchy::resetLogger", "Lock must be held by caller") - - pLogger->removeAllAppenders(); - pLogger->setAdditivity(true); - pLogger->setLevel(level); - } - - - - /************************************************************************** - * Implementation: Operators, Helper - **************************************************************************/ - - - -} // namespace Log4Qt diff --git a/src/log4qt/src/log4qt/hierarchy.h b/src/log4qt/src/log4qt/hierarchy.h deleted file mode 100644 index 18a90eb..0000000 --- a/src/log4qt/src/log4qt/hierarchy.h +++ /dev/null @@ -1,141 +0,0 @@ -/****************************************************************************** - * - * package: Log4Qt - * file: hierarchy.h - * created: September 2007 - * author: Martin Heinrich - * - * - * Copyright 2007 Martin Heinrich - * - * 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. - * - ******************************************************************************/ - -#ifndef LOG4QT_HIERARCHY_H -#define LOG4QT_HIERARCHY_H - - -/****************************************************************************** - * Dependencies - ******************************************************************************/ - -#include "log4qt/loggerrepository.h" - -#include -#include - - -/****************************************************************************** - * Declarations - ******************************************************************************/ - -namespace Log4Qt -{ - - /*! - * \brief The class Hierarchy implements a logger repository. - * - * \note All the functions declared in this class are thread-safe. - */ - class Hierarchy : public LoggerRepository - { - public: - Hierarchy(); - // Hierarchy(const Hierarchy &rOther); // Use compiler default - virtual ~Hierarchy(); - // Hierarchy &operator=(const Hierarchy &rOther); // Use compiler default - - public: - virtual bool exists(const QString &rName) const; - virtual Logger *logger(const QString &rName); - virtual QList loggers() const; - // JAVA: virtual Logger *logger(const String &rName, LoggerFactory *pFactory); - virtual Logger *rootLogger() const; - virtual Level threshold() const; - virtual void setThreshold(Level level); - virtual void setThreshold(const QString &rThreshold); - - // JAVA: void clear(); - virtual bool isDisabled(Level level); - virtual void resetConfiguration(); - virtual void shutdown(); - - // JAVA: virtual void addHierarchyEventListener(HierarchyEventListener *pEventListener); - // JAVA: virtual void emitNoAppenderWarning(Logger *plogger) const; - // JAVA: virtual void fireAddAppenderEvent(Logger *plogger, Appender *pAppender) const; - - // JAVA: void addRenderer(const QString &rClass, ObjectRenderer *pObjectRenderer); - // JAVA: QHash getRendererMap() const; - // JAVA: setRenderer(const QString &rClass, ObjectRenderer *pObjectRenderer); - - protected: -#ifndef QT_NO_DEBUG_STREAM - /*! - * Writes all object member variables to the given debug stream \a rDebug and - * returns the stream. - * - * - * %Hierarchy(loggers:6 threshold:"ALL" root-level:"DEBUG" root-appenders:0) - * - * \sa QDebug, operator<<(QDebug debug, const LoggerRepository &rLoggerRepository) - */ - virtual QDebug debug(QDebug &rdebug) const; -#endif - - private: - Logger *createLogger(const QString &rName); - void resetLogger(Logger *pLogger, Level level) const; - - private: - mutable QReadWriteLock mObjectGuard; - QHash mLoggers; - volatile bool mHandleQtMessages; - Level mThreshold; - Logger *mpRootLogger; - }; - - - /************************************************************************** - * Operators, Helper - **************************************************************************/ - - - /************************************************************************** - * Inline - **************************************************************************/ - - inline Logger *Hierarchy::rootLogger() const - { // QReadLocker locker(&mObjectGuard); // Constant for object lifetime - return mpRootLogger; } - - inline Level Hierarchy::threshold() const - { // QReadLocker locker(&mObjectGuard); // Level is threadsafe - return mThreshold; } - - inline void Hierarchy::setThreshold(Level level) - { // QReadLocker locker(&mObjectGuard); // Level is threadsafe - mThreshold = level; } - - inline bool Hierarchy::isDisabled(Level level) - { // QReadLocker locker(&mObjectGuard); // Level is threadsafe - return level < mThreshold; } - - -} // namespace Log4Qt - - -// Q_DECLARE_TYPEINFO(Log4Qt::Hierarchy, Q_COMPLEX_TYPE); // Use default - - -#endif // LOG4QT_HIERARCHY_H diff --git a/src/log4qt/src/log4qt/layout.cpp b/src/log4qt/src/log4qt/layout.cpp deleted file mode 100644 index 160f80d..0000000 --- a/src/log4qt/src/log4qt/layout.cpp +++ /dev/null @@ -1,91 +0,0 @@ -/****************************************************************************** - * - * package: Log4Qt - * file: layout.cpp - * created: September 2007 - * author: Martin Heinrich - * - * - * Copyright 2007 Martin Heinrich - * - * 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. - * - ******************************************************************************/ - - - -/****************************************************************************** - * Dependencies - ******************************************************************************/ - - -#include "log4qt/layout.h" - -#include -#include "log4qt/loggingevent.h" -#include "log4qt/logmanager.h" - - - -namespace Log4Qt -{ - - - /*************************************************************************** - * Declarations - **************************************************************************/ - - - - /************************************************************************** - * C helper functions - **************************************************************************/ - - - - /************************************************************************** - * Class implementation: Layout - **************************************************************************/ - - - QString Layout::contentType() const - { - return QString::fromLatin1("text/plain"); - } - - - void Layout::activateOptions() - { - } - - - QString Layout::endOfLine() - { - // There seams to be no function in Qt for this - -#ifdef Q_OS_WIN32 - return QLatin1String("\r\n"); -#endif // Q_OS_WIN32 -//#ifdef Q_OS_MAC -// return QLatin1String("\r"); -//#endif // Q_OS_MAC - return QLatin1String("\n"); - } - - - /************************************************************************** - * Implementation: Operators, Helper - **************************************************************************/ - - -} // namespace Log4Qt diff --git a/src/log4qt/src/log4qt/layout.h b/src/log4qt/src/log4qt/layout.h deleted file mode 100644 index 42f3b3e..0000000 --- a/src/log4qt/src/log4qt/layout.h +++ /dev/null @@ -1,156 +0,0 @@ -/****************************************************************************** - * - * package: Log4Qt - * file: layout.h - * created: September 2007 - * author: Martin Heinrich - * - * - * Copyright 2007 Martin Heinrich - * - * 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. - * - ******************************************************************************/ - -#ifndef LOG4QT_LAYOUT_H -#define LOG4QT_LAYOUT_H - - -/****************************************************************************** - * Dependencies - ******************************************************************************/ - -#include "log4qt/helpers/logobject.h" - -#include "log4qt/helpers/logobjectptr.h" -#include "log4qt/log4qt.h" - - -/****************************************************************************** - * Declarations - ******************************************************************************/ - -namespace Log4Qt -{ - - class LoggingEvent; - - /*! - * \brief The class Layout is the base class for all layouts. - * - * \note The ownership and lifetime of objects of this class are managed. See - * \ref Ownership "Object ownership" for more details. - */ - class Layout : public LogObject - { - Q_OBJECT - - /*! - * The property holds the content type of the layout. - * - * \sa contentType() - */ - Q_PROPERTY(QString footercontentType READ contentType) - /*! - * The property holds the footer used by the layout. - * - * \sa footer(), setFooter() - */ - Q_PROPERTY(QString footer READ footer WRITE setFooter) - /*! - * The property holds the header used by the layout. - * - * \sa header(), setHeader() - */ - Q_PROPERTY(QString header READ header WRITE setHeader) - - public: - Layout(QObject *pParent = 0); - virtual ~Layout(); - private: - Layout(const Layout &rOther); // Not implemented - Layout &operator=(const Layout &rOther); // Not implemented - - public: - virtual QString contentType() const; - QString footer() const; - QString header() const; - // JAVA: virtual bool ignoresThrowable() const; - QString name() const; - void setFooter(const QString &rFooter); - void setHeader(const QString &rHeader); - void setName(const QString &rName); - // JAVA: void setIgnoresThrowable(bool) const; - - virtual void activateOptions(); - virtual QString format(const LoggingEvent &rEvent) = 0; - - /*! - * Returns the end of line seperator for the operating system. - * - * Windows: \\r\\n - * Mac: \\r - * UNIX: \\n - */ - static QString endOfLine(); - - // Member variables - private: - QString mFooter; - QString mHeader; - }; - - - /************************************************************************** - * Operators, Helper - **************************************************************************/ - - - /************************************************************************** - * Inline - **************************************************************************/ - - inline Layout::Layout(QObject *pParent) : - LogObject(pParent) - {} - - inline Layout::~Layout() - {} - - inline QString Layout::footer() const - { return mFooter; } - - inline QString Layout::header() const - { return mHeader; } - - inline QString Layout::name() const - { return objectName(); } - - inline void Layout::setFooter(const QString &rFooter) - { mFooter = rFooter; } - - inline void Layout::setHeader(const QString &rHeader) - { mHeader = rHeader; } - - inline void Layout::setName(const QString &rName) - { setObjectName(rName); } - - -} // namespace Log4Qt - - -// Q_DECLARE_TYPEINFO(Log4Qt::Layout, Q_COMPLEX_TYPE); // Use default -Q_DECLARE_TYPEINFO(Log4Qt::LogObjectPtr, Q_MOVABLE_TYPE); - - -#endif // LOG4QT_LAYOUT_H diff --git a/src/log4qt/src/log4qt/level.cpp b/src/log4qt/src/log4qt/level.cpp deleted file mode 100644 index a55038f..0000000 --- a/src/log4qt/src/log4qt/level.cpp +++ /dev/null @@ -1,204 +0,0 @@ -/****************************************************************************** - * - * package: Log4Qt - * file: level.cpp - * created: September 2007 - * author: Martin Heinrich - * - * - * Copyright 2007 Martin Heinrich - * - * 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. - * - ******************************************************************************/ - - - -/****************************************************************************** - * Dependencies - ******************************************************************************/ - - -#include "log4qt/level.h" - -#include -#include -#include -#include "log4qt/logger.h" - - -namespace Log4Qt -{ - - - /************************************************************************** - * Declarations - **************************************************************************/ - - - - /************************************************************************** - * C helper functions - **************************************************************************/ - - - LOG4QT_DECLARE_STATIC_LOGGER(logger, Log4Qt::Level) - - - - /************************************************************************** - * Class implementation: Level - **************************************************************************/ - - - int Level::syslogEquivalent() const - { - // QMutexLocker locker(&mObjectGuard); // Read/Write of int is safe - - switch (mValue) - { - case NULL_INT: - case ALL_INT: - case TRACE_INT: - case DEBUG_INT: - return 7; - case INFO_INT: - return 6; - case WARN_INT: - return 4; - case ERROR_INT: - return 3; - case FATAL_INT: - case OFF_INT: - return 0; - default: - Q_ASSERT_X(false, "Level::syslogEquivalent()", "Unknown level value"); - return 7; - } - } - - - QString Level::toString() const - { - // QMutexLocker locker(&mObjectGuard); // Read/Write of int is safe - - const char *p_context = "Level"; - - switch (mValue) - { - case NULL_INT: - return QCoreApplication::translate(p_context, "NULL"); - case ALL_INT: - return QCoreApplication::translate(p_context, "ALL"); - case TRACE_INT: - return QCoreApplication::translate(p_context, "TRACE"); - case DEBUG_INT: - return QCoreApplication::translate(p_context, "DEBUG"); - case INFO_INT: - return QCoreApplication::translate(p_context, "INFO"); - case WARN_INT: - return QCoreApplication::translate(p_context, "WARN"); - case ERROR_INT: - return QCoreApplication::translate(p_context, "ERROR"); - case FATAL_INT: - return QCoreApplication::translate(p_context, "FATAL"); - case OFF_INT: - return QCoreApplication::translate(p_context, "OFF"); - default: - Q_ASSERT_X(false, "Level::toString()", "Unknown level value"); - return QCoreApplication::translate(p_context, "NULL"); - } - } - - - Level Level::fromString(const QString &rLevel, bool *pOk) - { - const char *p_context = "Level"; - if (pOk) - *pOk = true; - - if (rLevel == QLatin1String("OFF") || - rLevel == QCoreApplication::translate(p_context, "OFF")) - return OFF_INT; - if (rLevel == QLatin1String("FATAL") || - rLevel == QCoreApplication::translate(p_context, "FATAL")) - return FATAL_INT; - if (rLevel == QLatin1String("ERROR") || - rLevel == QCoreApplication::translate(p_context, "ERROR")) - return ERROR_INT; - if (rLevel == QLatin1String("WARN") || - rLevel == QCoreApplication::translate(p_context, "WARN")) - return WARN_INT; - if (rLevel == QLatin1String("INFO") || - rLevel == QCoreApplication::translate(p_context, "INFO")) - return INFO_INT; - if (rLevel == QLatin1String("DEBUG") || - rLevel == QCoreApplication::translate(p_context, "DEBUG")) - return DEBUG_INT; - if (rLevel == QLatin1String("TRACE") || - rLevel == QCoreApplication::translate(p_context, "TRACE")) - return TRACE_INT; - if (rLevel == QLatin1String("ALL") || - rLevel == QCoreApplication::translate(p_context, "ALL")) - return ALL_INT; - if (rLevel == QLatin1String("NULL") || - rLevel == QCoreApplication::translate(p_context, "NULL")) - return NULL_INT; - - logger()->warn("Use of invalid level string '%1'. Using 'Level::NULL_INT' instead.", rLevel); - if (pOk) - *pOk = false; - return NULL_INT; - } - - - - /************************************************************************** - * Implementation: Operators, Helper - **************************************************************************/ - - -#ifndef QT_NO_DATASTREAM - QDataStream &operator<<(QDataStream &rStream, - const Level &rLevel) - { - quint8 l = rLevel.mValue; - rStream << l; - return rStream; - } - - - QDataStream &operator>>(QDataStream &rStream, - Level &rLevel) - { - quint8 l; - rStream >> l; - rLevel.mValue = (Level::Value)l; - return rStream; - } -#endif // QT_NO_DATASTREAM - - -#ifndef QT_NO_DEBUG_STREAM - QDebug operator<<(QDebug debug, - const Level &rLevel) - { - debug.nospace() << "Level(" - << rLevel.toString() - << ")"; - return debug.space(); - } -#endif // QT_NO_DEBUG_STREAM - - -} // namespace Log4Qt diff --git a/src/log4qt/src/log4qt/level.h b/src/log4qt/src/log4qt/level.h deleted file mode 100644 index 93914c2..0000000 --- a/src/log4qt/src/log4qt/level.h +++ /dev/null @@ -1,193 +0,0 @@ -/****************************************************************************** - * - * package: Log4Qt - * file: level.h - * created: September 2007 - * author: Martin Heinrich - * - * - * Copyright 2007 Martin Heinrich - * - * 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. - * - ******************************************************************************/ - -#ifndef LOG4QT_LEVEL_H -#define LOG4QT_LEVEL_H - - -/****************************************************************************** - * Dependencies - ******************************************************************************/ - -#include -#include -#include "log4qt/log4qt.h" - - -/****************************************************************************** - * Declarations - ******************************************************************************/ - -namespace Log4Qt -{ - - /*! - * \brief The class Level defines the level of a logging event. - * - * \note All the functions declared in this class are thread-safe. - */ - class Level - { - public: - // Comparisson operators rely on the order: - // NULL_INT < ALL_INT < TRACE_INT < ... - // Serialisation uses unsigned 8 bit int - - /*! - * The enumeration Value contains all possible Level values. - */ - enum Value - { - /*! NULL_INT is used for no level has been specified */ - NULL_INT = 0, - ALL_INT = 32, - TRACE_INT = 64, - DEBUG_INT = 96, - INFO_INT = 128, - WARN_INT = 150, - ERROR_INT = 182, - FATAL_INT = 214, - OFF_INT = 255 - }; - - public: - Level(Value value = NULL_INT); - // Level(const Level &rOther); // Use compiler default - // virtual ~Level(); // Use compiler default - // Level &operator=(const Level &rOther); // Use compiler default - - int syslogEquivalent() const; - int toInt() const; - - bool operator==(const Level &rOther) const; - bool operator!=(const Level &rOther) const; - bool operator<(const Level &rOther) const; - bool operator<=(const Level &rOther) const; - bool operator>(const Level &rOther) const; - bool operator>=(const Level &rOther) const; - QString toString() const; - - static Level fromString(const QString &rName, bool *pOk = 0); - - private: - // QMutex mObjectGuard; - volatile Value mValue; - -#ifndef QT_NO_DATASTREAM - // Needs to be friend to stream objects - friend QDataStream &operator<<(QDataStream &rStream, - const Level &rLevel); - friend QDataStream &operator>>(QDataStream &rStream, - Level &rLevel); -#endif // QT_NO_DATASTREAM - }; - - - /************************************************************************** - * Operators, Helper - **************************************************************************/ - -#ifndef QT_NO_DATASTREAM - /*! - * \relates Level - * - * Writes the given error \a rLevel to the given stream \a rStream, - * and returns a reference to the stream. - */ - QDataStream &operator<<(QDataStream &rStream, - const Level &rLevel); - - /*! - * \relates Level - * - * Reads an error from the given stream \a rStream into the given - * error \a rLevel, and returns a reference to the stream. - */ - QDataStream &operator>>(QDataStream &rStream, - Level &rLevel); -#endif // QT_NO_DATASTREAM - -#ifndef QT_NO_DEBUG_STREAM - /*! - * \relates Level - * - * Writes all object member variables to the given debug stream \a rDebug - * and returns the stream. - * - * - * %Level("ERROR") - * - * \sa QDebug - */ - QDebug operator<<(QDebug debug, - const Level &rLevel); -#endif // QT_NO_DEBUG_STREAM - - - /************************************************************************** - * Inline - **************************************************************************/ - - - inline Level::Level(Value value) : - mValue(value) - {} - - inline int Level::toInt() const - { // QMutexLocker locker(&mObjectGuard); // Read/Write of int is safe - return mValue; } - - inline bool Level::operator==(const Level &rOther) const - { // QMutexLocker locker(&mObjectGuard); // Read/Write of int is safe - return mValue == rOther.mValue; } - - inline bool Level::operator!=(const Level &rOther) const - { // QMutexLocker locker(&mObjectGuard); // Read/Write of int is safe - return mValue != rOther.mValue; } - - inline bool Level::operator<(const Level &rOther) const - { // QMutexLocker locker(&mObjectGuard); // Read/Write of int is safe - return mValue < rOther.mValue; } - - inline bool Level::operator<=(const Level &rOther) const - { // QMutexLocker locker(&mObjectGuard); // Read/Write of int is safe - return mValue <= rOther.mValue; } - - inline bool Level::operator>(const Level &rOther) const - { // QMutexLocker locker(&mObjectGuard); // Read/Write of int is safe - return mValue > rOther.mValue; } - - inline bool Level::operator>=(const Level &rOther) const - { // QMutexLocker locker(&mObjectGuard); // Read/Write of int is safe - return mValue >= rOther.mValue; } - - -} // namespace Log4Qt - - -Q_DECLARE_METATYPE(Log4Qt::Level) -Q_DECLARE_TYPEINFO(Log4Qt::Level, Q_MOVABLE_TYPE); - - -#endif // LOG4QT_LEVEL_H diff --git a/src/log4qt/src/log4qt/log4qt.cpp b/src/log4qt/src/log4qt/log4qt.cpp deleted file mode 100644 index 9378f46..0000000 --- a/src/log4qt/src/log4qt/log4qt.cpp +++ /dev/null @@ -1,58 +0,0 @@ -/****************************************************************************** - * - * package: Log4Qt - * file: logging.cpp - * created: September 2007 - * author: Martin Heinrich - * - * - * Copyright 2007 Martin Heinrich - * - * 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. - * - *****************************************************************************/ - - - -/****************************************************************************** - *Dependencies - ******************************************************************************/ - - -#include "log4qt/log4qt.h" - - - -namespace Log4Qt -{ - - - /************************************************************************** - * Declarations - **************************************************************************/ - - - - /************************************************************************** - * C helper functions - **************************************************************************/ - - - - /************************************************************************** - *Implementation: Operators, Helper - **************************************************************************/ - - - -} // namespace Log4Qt diff --git a/src/log4qt/src/log4qt/log4qt.h b/src/log4qt/src/log4qt/log4qt.h deleted file mode 100644 index 73c3cfe..0000000 --- a/src/log4qt/src/log4qt/log4qt.h +++ /dev/null @@ -1,614 +0,0 @@ -/****************************************************************************** - * - * package: Log4Qt - * file: logging.h - * created: September 2007 - * author: Martin Heinrich - * - * - * changes: Sep 2008, Martin Heinrich: - * - Added a compile time version check for the Qt version - * Jan 2009, Martin Heinrich: - * - Updated documentation and version information for version 0.2 - * Feb 2009, Martin Heinrich: - * - Updated version information for version 0.3 - * - * - * Copyright 2007 - 2009 Martin Heinrich - * - * 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. - * - ******************************************************************************/ - -#ifndef LOG4QT_H -#define LOG4QT_H - - -/*! - * \mainpage - * - * %Log4Qt is a C++ port of the Apache Software Foundation Log4j package - * using the Trolltech Qt Framework. - * - * The documentation describes classes and methods that have been added or - * changed compared to Log4j. - * - * The following sections are describing the implementation in more detail: - * - \ref Changes "Differences to Log4j" - * - \ref Ownership "Object ownership" - * - \ref LogLog "Logging within the package" - * - \ref Init "Initialization procedure" - * - \ref Env "Environment Variables" - * - \ref Undocumented "Undocumented functions" - * - \ref Assumptions "Assumptions" - * - * \author Martin Heinrich - * \version 0.3 (January 2009) - * - */ - -/*! - * \page Changes Differences to Log4j - * - * The following fundamental differences exist between %Log4Qt and Log4j: - * - * - As a JAVA package Log4j does not have to manage object ownership and - * lifetime in the same way then it is required in C++. For details on - * how object ownership is handled see \ref Ownership "Object ownership". - * - The package uses itself for its internal logging similar to Log4j 1.3. - * For details see \ref LogLog "Logging within the package". - * - The configuration using system properties was replaced with a combination - * of environment variables and application settings. For details see - * \ref Env "Environment Variables". - * - Custom levels are not supported. - * - Multiple Logger Repositories are not supported - * - * The following classes have been changed: - * - * - \ref Log4Qt::AppenderSkeleton "AppenderSkeleton" - * - The procedure of checking, if logging is possible, originally used by - * \ref Log4Qt::WriterAppender "WriterAppender" was generalised and is used - * in \ref Log4Qt::AppenderSkeleton "AppenderSkeleton" and derived classes - * (\ref Log4Qt::AppenderSkeleton::checkEntryConditions() "checkEntryConditions()"). - * - The \ref Log4Qt::AppenderSkeleton::doAppend() "doAppend()" member function will - * check the entry conditions by calling the sub-class specific - * \ref Log4Qt::AppenderSkeleton::checkEntryConditions() "checkEntryConditions()". - * If successful the sub-class specific - * \ref Log4Qt::AppenderSkeleton::append() "append()" function is called. - * - * - Configurator - * - Configure functions return a boolean indicating, if the configuration - * was successful. - * - Configure errors are accessible over - * \ref Log4Qt::ConfiguratorHelper::configureError() - * "ConfiguratorHelper::configureError()". - * - Watching for configuration file changes is a function performed - * centrally by the \ref Log4Qt::ConfiguratorHelper "ConfiguratorHelper". - * The class provides signals to notify on configuration change and errors. - * - The class \ref Log4Qt::PropertyConfigurator "PropertyConfigurator" was - * extended to be able to read configuration data from a QSettings object. - * - * - \ref Log4Qt::Level "Level" - * - A new value \ref Log4Qt::Level::NULL_INT "Level::NULL_INT" was - * introduced to indicate there is no level set. - * - * - \ref Log4Qt::Logger "Logger" - * - The method \ref Log4Qt::Logger::isEnabledFor() "isEnabledFor()" - * does also take the repository threshold into account. - * - Several overloaded convenience member function are available to log - * messages with arguments of different types. - * - Two macros, \ref Log4Qt::LOG4QT_DECLARE_STATIC_LOGGER "LOG4QT_DECLARE_STATIC_LOGGER" - * and \ref Log4Qt::LOG4QT_DECLARE_QCLASS_LOGGER "LOG4QT_DECLARE_QCLASS_LOGGER", - * allows retrieving and caching of a pointer to a logger object. - * - * - \ref Log4Qt::LogManager "LogManager" - * - A QtMessage handler can be installed via - * \ref Log4Qt::LogManager::setHandleQtMessages() "setHandleQtMessages()", - * to redirect all messages created by calls to qDebug(), qWarning(), - * qCritical() and qFatal() to a logger. The logger is named Qt and can be - * accessed using \ref Log4Qt::LogManager::qtLogger() "qtLogger()". - * - The initialisation procedure is available over a public method - * (\ref Log4Qt::LogManager::startup() "startup()"). - * - The LogManager provides access to the logger used internally by the - * package (\ref Log4Qt::LogManager::logLogger() "logLogger()") and to - * its default initialisation procedure - * (\ref Log4Qt::LogManager::configureLogLogger() "configureLogLogger()"). - * - * - \ref Log4Qt::WriterAppender "WriterAppender" - * - The class will call \ref Log4Qt::WriterAppender::handleIoErrors() - * "handleIoErrors()" after all I/O operations. Sub-classes should - * re-implement the function to handle errors. - * - * The following classes have been added: - * - * - An additional appender class, \ref Log4Qt::DebugAppender "DebugAppender", - * was added. The class appends logging events to the platform specific debug - * output. - * - Various helper class have been introduced: - * - \ref Log4Qt::ClassLogger "ClassLogger": The class ClassLogger provides - * logging for a QObject derived class. - * - \ref Log4Qt::ConfiguratorHelper "ConfiguratorHelper": The class - * ConfiguratorHelper provides a configuration file watch and last error - * for configurator classes. - * - \ref Log4Qt::DateTime "DateTime": The class DateTime provides extended - * functionality for QDateTime. - * - \ref Log4Qt::LogError "LogError": The class LogError represents an error. - * - \ref Log4Qt::Factory "Factory": The class Factory provides factories - * for Appender, Filter and Layout objects. - * - \ref Log4Qt::InitialisationHelper "InitialisationHelper": The class - * InitialisationHelper performs static initialisation tasks. - * - \ref Log4Qt::LogObject "LogObject": The class LogObject is the common - * base class for many classes in the package. - * - \ref Log4Qt::LogObjectPtr "LogObjectPtr": The class LogObjectPtr - * implements automatic reference counting for LogObject objects. - * - \ref Log4Qt::PatternFormatter "PatternFormatter": The class - * PatternFormatter formats a logging event based on a pattern string. - * - \ref Log4Qt::Properties "Properties": The class Properties implements a - * JAVA property hash. - */ - -/*! - * \page Ownership Object ownership - * - * In difference to the JAVA Log4j package %Log4Qt must manage ownership and - * lifetime of the objects used. This is non trivial as objects are created - * and used in different ways. - * - * In general an object can be created explicitly for example an application - * may create Loggers, Appenders and Layouts during creation of a QApplication - * object. But they can also be automatically created by the package on - * startup using a \ref Log4Qt::PropertyConfigurator "PropertyConfigurator" - * configuration file. Objects may also be created the one way and then used - * the other. Object may be used by multiple other objects. A Layout for example - * may be used by multiple Appenders. Objects are also created from multiple - * threads. The creation may happen during static initialisation and the - * deletion during static de-initialization. - * - * The parent child model used by QObject cannot be used to handle this. It - * cannot automatically delete an object that is used by multiple others as - * for example an Appender used by multiple Loggers. In addition to this - * QObjects and their children must reside in the same thread. This would - * either mean to impose restriction on how objects can be created or to move - * objects to a specific thread. - * - * To allow an automatic deletion of not required objects the package - * implements reference counting for Appenders, Layouts and Filters. The - * reference counting is implemented in \ref Log4Qt::LogObject "LogObject", - * which is used as a common base class. The reference count can be explicitly - * changed using the methods \ref Log4Qt::LogObject::retain() "retain()" and - * \ref Log4Qt::LogObject::release() "release()". Alternatively an auto pointer - * is available \ref Log4Qt::LogObjectPtr "LogObjectPtr", which is used - * throughout the package. - * - * The reference counting mechanism will test, if an object has a QObject - * parent object set. If a parent is set, the object will not be deleted, if - * the reference count reaches 0. This allows to mix the reference counted - * paradigm with the QObject parent child one. - * - * The following example configures a logger and uses reference counting to - * manage the ownership of objects. - * - * \code - * // Create layout - * TTCCLayout *p_layout = new TTCCLayout(); - * - * // Create appender - * ConsoleAppender *p_appender = new ConsoleAppender(p_layout, ConsoleAppender::STDOUT_TARGET); - * p_appender->activateOptions(); - * - * // Get logger - * Logger *p_logger = Logger::logger("MyClass"); - * p_logger->addAppender(p_appender); - * - * // ... - * - * // Remove appender from Logger - * p_logger->removeAllAppenders(); // p_appender and p_layout are deleted here - * \endcode - * - * The following example configures a logger and uses QObject ownership of - * objects. - * - * \code - * QObject *p_parent = new MyObject; - * - * // Create objects - * ConsoleAppender *p_appender = new ConsoleAppender(p_parent); - * TTCCLayout *p_layout = new TTCCLayout(p_appender); - * - * // Configure appender - * p_appender->setTarget(ConsoleAppender::STDOUT_TARGET); - * p_appender->setLayout(p_layout); - * p_appender->activateOptions(); - * - * // Get logger - * Logger *p_logger = Logger::logger("MyClass"); - * p_logger->addAppender(p_appender); - * - * // ... - * - * // Remove appender from Logger - * p_logger->removeAllAppenders(); - * - * delete p_parent; // p_appender and p_layout are deleted here - * \endcode - * - * The following example shows how to use objects created on the stack. - * - * \code - * { - * // Create layout - * TTCCLayout layout; - * layout.retain(); - * - * // Create appender - * ConsoleAppender appender(&layout, ConsoleAppender::STDOUT_TARGET); - * appender.retain(); - * appender.activateOptions(); - * - * // Get logger - * Logger *p_logger = Logger::logger("MyClass"); - * p_logger->addAppender(&appender); - * - * // ... - * - * // Remove appender from Logger - * p_logger->removeAllAppenders(); // Without retain() program crashes here - * - * } // p_appender and p_layout are deleted here - * \endcode - */ - -/*! - * \page LogLog Logging within the package - * - * The package uses itself for logging similar to Log4j 1.3. This brings much - * more flexibility over logging to stdout, stderr like in Log4j 1.2 using - * logLog. It also enables the program to capture and handle errors raised by - * the package. - * - * Using this approach introduces the issue of recursion. The following example - * explains a situation where this happens. Let's say all logger are configured - * to be additive and only the root logger has an appender set. The appender - * is a \ref Log4Qt::FileAppender "FileAppender". During the logging of an - * event an I/O error occurs. The \ref Log4Qt::FileAppender "FileAppender" logs - * an event by itself using the logger %Log4Qt::FileAppender. The event is - * passed to the root logger, which calls then the \ref Log4Qt::FileAppender - * "FileAppender". This causes another I/O error, which is logged by - * the \ref Log4Qt::FileAppender "FileAppender". - * - * To avoid an endless loop the appender will drop the event on a recursive - * invocation. This check is done by \ref Log4Qt::AppenderSkeleton - * "AppenderSkeleton" in \ref Log4Qt::AppenderSkeleton::doAppend() - * "doAppend()". - * - * The problem only occurs, if a logger, appender, layout or filter log an - * event while an event is appended. Neither the logger class nor any of the - * layout or filter classes log events during appending of an event. Most of - * the appender classes may log errors during appending. Only the - * \ref Log4Qt::ListAppender "ListAppender" and - * \ref Log4Qt::ListAppender "ConsoleAppender" are not logging events. - * - * The default configuration uses two \ref Log4Qt::ListAppender - * "ConsoleAppender", one for stderr and one for stdout. No event will be - * dropped, because no recursive invocations can occur. - */ - -/*! - * \page Init Initialization procedure - * - * The package is initialised in two stages. The first stage takes place during - * static initialization. The second stage takes place when the - * \ref Log4Qt::LogManager "LogManager" singleton is created. - * - * During static initialisation the \ref Log4Qt::InitialisationHelper - * "InitialisationHelper" singleton is created . On construction it captures - * the program startup time, reads the required values from the system - * environment and registers the package types with the Qt type system. - * - * The \ref Log4Qt::LogManager "LogManager" singleton is created on first use. - * The creation is usually triggered by the request for a \ref Log4Qt::Logger - * "Logger" object. The call to \ref Log4Qt::Logger::logger() - * "Logger::logger()" is passed through to \ref Log4Qt::LogManager::logger() - * "LogManager::logger()". On creation the \ref Log4Qt::LogManager "LogManager" - * creates a \ref Log4Qt::Hierarchy "Hierarchy" object as logger repository. - * - * After the singleton is created the logging of the package is configured to - * its default by a call to \ref Log4Qt::LogManager::configureLogLogger() - * "LogManager::configureLogLogger()". The logger - * \ref Log4Qt::LogManager::logLogger() "logLogger()" is configured to be not - * additive. Messages with the level \ref Log4Qt::Level::ERROR_INT - * "Level::ERROR_INT" and \ref Log4Qt::Level::FATAL_INT "Level::FATAL_INT" are - * written to \c stderr using a ConsoleAppender. The remaining messages are - * written to \c stdout using a second ConsoleAppender. The level is read from - * the system environment or application settings using - * \ref Log4Qt::InitialisationHelper::setting() - * "InitialisationHelper::setting()" with the key \c Debug. If a level value - * is found, but it is not a valid Level string, - * \ref Log4Qt::Level::DEBUG_INT "Level::DEBUG_INT" is used. If no level string - * is found \ref Log4Qt::Level::ERROR_INT "Level::ERROR_INT" is used. - * - * Once the logging is configured the package is initialised by a call to - * \ref Log4Qt::LogManager::startup() "LogManager::startup()". The function - * will test for the setting \c DefaultInitOverride in the system environment - * and application settings using \ref Log4Qt::InitialisationHelper::setting() - * "InitialisationHelper::setting()". If the value is present and set to - * anything else then \c false, the initialisation is aborted.
- * The system environment and application settings are tested for the setting - * \c Configuration. If it is found and it is a valid path to a file, the - * package is configured with the file using - * \ref Log4Qt::PropertyConfigurator::doConfigure(const QString &, LoggerRepository *) - * "PropertyConfigurator::doConfigure()". If the setting \c Configuration is - * not available and a QCoreApplication object is present, the application - * settings are tested for a group \c Log4Qt/Properties. If the group exists, - * the package is configured with the setting using the - * \ref Log4Qt::PropertyConfigurator::doConfigure(const QSettings &r, LoggerRepository *) - * "PropertyConfiguratordoConfigure()". If neither a configuration file nor - * configuration settings could be found, the current working directory is - * searched for the file \c "log4qt.properties". If it is found, the package - * is configured with the file using - * \ref Log4Qt::PropertyConfigurator::doConfigure(const QString &, LoggerRepository *) - * "PropertyConfigurator::doConfigure()". - * - * The following example shows how to use application settings to initialise the - * package. - * - * \code - * # file: myapplication.h - * - * #include qapplication.h - * - * class MyApplication : public QApplication - * { - * Q_OBJECT - * - * public: - * MyApplication(); - * ~MyApplication(); - * void setupLog4Qt(); - * } - * \endcode - * \code - * # file: myapplication.cpp - * - * #include myapplication.h - * - * MyApplication::MyApplication( - * { - * // Set Application data to allow Log4Qt initialisation to read the - * // correct values - * setApplicationName("MyApplication"); - * setOrganisationName("MyOrganisation"); - * setOrganizationDomain("www.myorganisation.com"); - * - * // Log first message, which initialises Log4Qt - * Log4Qt::Logger::logger("MyApplication")->info("Hello World"); - * } - * - * MyApplication::~MyApplication() - * { - * } - * - * void MyApplication::setupLog4Qt() - * { - * QSettings s; - * - * // Set logging level for Log4Qt to TRACE - * s.beginGroup("Log4Qt"); - * s.setValue("Debug", "TRACE"); - * - * // Configure logging to log to the file C:/myapp.log using the level TRACE - * s.beginGroup("Properties"); - * s.setValue("log4j.appender.A1", "org.apache.log4j.FileAppender"); - * s.setValue("log4j.appender.A1.file", "C:/myapp.log"); - * s.setValue("log4j.appender.A1.layout", "org.apache.log4j.TTCCLayout"); - * s.setValue("log4j.appender.A1.layout.DateFormat", "ISO8601"); - * s.setValue("log4j.rootLogger", "TRACE, A1"); - * - * // Settings will become active on next application startup - * } - * \endcode - */ - -/*! - * \page Env Environment Variables - * - * The package uses environment variables to control the initialization - * procedure. The environment variables replace the system property entries - * used by Log4j. - * - * For compability reasons the Log4j entry is recognised. Alternatively a - * environment variable style Log4Qt form can be used. The following entries - * are used: - * - * - LOG4QT_DEBUG
- * The variable controls the \ref Log4Qt::Level "Level" value for the - * logger \ref Log4Qt::LogManager::logLogger() "LogManager::logLogger()". - * If the value is a valid \ref Log4Qt::Level "Level" string, the level for - * the is set to the level. If the value is not a valid - * \ref Log4Qt::Level "Level" string, \ref Log4Qt::Level::DEBUG_INT - * "DEBUG_INT" is used. Otherwise \ref Log4Qt::Level::ERROR_INT "ERROR_INT" - * is used. - * - \ref Log4Qt::LogManager::configureLogLogger() - * "LogManager::configureLogLogger()" - * - * - LOG4QT_DEFAULTINITOVERRIDE
- * The variable controls the \ref Init "initialization procedure" performed - * by the \ref Log4Qt::LogManager "LogManager" on startup. If it is set to - * any other value then \c false the \ref Init "initialization procedure" - * is skipped. - * - \ref Log4Qt::LogManager::startup() "LogManager::startup()" - * - * - LOG4QT_CONFIGURATION
- * The variable specifies the configuration file used for initialising the - * package. - * - \ref Log4Qt::LogManager::startup() "LogManager::startup()" - * - * - LOG4QT_CONFIGURATORCLASS
- * The variable specifies the configurator class used for initialising the - * package. - * - * Environment variables are read during static initialisation on creation of - * the \ref Log4Qt::InitialisationHelper "InitialisationHelper". They can be - * accessed by calling \ref Log4Qt::InitialisationHelper::environmentSettings() - * "InitialisationHelper::environmentSettings()". - * - * All settings can also be made in the application settings under the group - * \c %Log4Qt. For example the environment variable \c LOG4QT_DEBUG is - * equivalent to the setting \c Log4Qt/Debug. If an environment variable is - * set it takes precedence over the application setting. Settings are only - * used, if an QApplication object is available, when the - * \ref Log4Qt::LogManager "LogManager" is - * initialised (see \ref Log4Qt::InitialisationHelper::setting() - * "InitialisationHelper::setting()" for details). - */ - -/*! - * \page Undocumented Undocumented functions - * - * In general it was tried to avoid the usage of undocumented features of Qt. - * Nice to have features like for example Q_DECLARE_PRIVATE are not used. Only - * features that would have been resulted in re-coding the same functionality - * are used. - * - * - QT_WA: The macro is used to call Windows A/W functions - * - \ref Log4Qt::DebugAppender "DebugAppender" - * - QBasicAtomicPointer: The class is used instead of QAtomicPointer, because - * it allows the initialisation as plain old data type. - * - \ref Log4Qt::LOG4QT_GLOBAL_STATIC "LOG4QT_GLOBAL_STATIC" - * - \ref Log4Qt::LOG4QT_IMPLEMENT_INSTANCE "LOG4QT_IMPLEMENT_INSTANCE" - * - \ref Log4Qt::LOG4QT_DECLARE_STATIC_LOGGER "LOG4QT_DECLARE_STATIC_LOGGER" - * - Q_BASIC_ATOMIC_INITIALIZER: The macro is used to initialise QAtomicPointer - * objects as plain old data type. - * - \ref Log4Qt::LOG4QT_GLOBAL_STATIC "LOG4QT_GLOBAL_STATIC" - * - \ref Log4Qt::LOG4QT_IMPLEMENT_INSTANCE "LOG4QT_IMPLEMENT_INSTANCE" - * - \ref Log4Qt::LOG4QT_DECLARE_STATIC_LOGGER "LOG4QT_DECLARE_STATIC_LOGGER" - */ - -/*! - * \page Assumptions Assumptions - * - * The following assumptions are used throughout the package: - * - * - Reading / writing of bool or int is thread-safe, if declared volatile - * - \ref Log4Qt::ListAppender "ListAppender" - * - \ref Log4Qt::AppenderSkeleton "AppenderSkeleton" - * - \ref Log4Qt::ConsoleAppender "ConsoleAppender" - * - \ref Log4Qt::FileAppender "FileAppender" - * - \ref Log4Qt::Hierarchy "Hierarchy" - * - \ref Log4Qt::Level "Level" - * - \ref Log4Qt::Logger "Logger" - * - \ref Log4Qt::WriterAppender "WriterAppender" - * - \ref Log4Qt::Layout::format() "Layout::format()" is implemented reentrant - * in all sub-classes. - * - \ref Log4Qt::AppenderSkeleton "AppenderSkeleton" - * - Being able to use singleton objects during static de-initialization without - * order issues is more valuable then their destruction. - * - \ref Log4Qt::LogManager "LogManager" - * - \ref Log4Qt::LOG4QT_GLOBAL_STATIC "LOG4QT_GLOBAL_STATIC" - * - \ref Log4Qt::LOG4QT_IMPLEMENT_INSTANCE "LOG4QT_IMPLEMENT_INSTANCE" - */ - -/****************************************************************************** - * Dependencies - ******************************************************************************/ - -#include - -#if QT_VERSION < QT_VERSION_CHECK(4, 3, 0) -# error "Log4Qt requires Qt version 4.3.0 or higher" -#endif - - -/****************************************************************************** - * Declarations - ******************************************************************************/ - -/*! - * \brief The namespace %Log4Qt encloses all parts of the package. - */ -namespace Log4Qt -{ - /*! - * This macro expands a numeric value of the form 0xMMmmPP (MM = major, - * mm = minor, PP = patch) that specifies Log4Qt's version number. - * This is the version against which the application is compiled. - * - * \sa \ref Log4Qt::LOG4QT_VERSION_STR "LOG4QT_VERSION_STR", - * \ref Log4Qt::LogManager::version() "LogManager::version()" - */ - #define LOG4QT_VERSION 0x000200 - - /*! - * The macro expands to a string that specifies the Log4Qt's version - * number. This is the version against which the application is compiled. - * - * \sa \ref Log4Qt::LOG4QT_VERSION "LOG4QT_VERSION", - * \ref Log4Qt::LogManager::version() "LogManager::version()" - */ - #define LOG4QT_VERSION_STR "0.3.0" - - enum ErrorCode - { - OK = 0, - // AppenderSkeleton, FileAppender, WriterAppender - APPENDER_ACTIVATE_MISSING_LAYOUT_ERROR, - APPENDER_ACTIVATE_MISSING_WRITER_ERROR, - APPENDER_ACTIVATE_MISSING_FILE_ERROR, - APPENDER_CLOSED_ERROR, - APPENDER_INVALID_PATTERN_ERROR, - APPENDER_NO_OPEN_FILE_ERROR, - APPENDER_NOT_ACTIVATED_ERROR, - APPENDER_OPENING_FILE_ERROR, - APPENDER_RENAMING_FILE_ERROR, - APPENDER_REMOVE_FILE_ERROR, - APPENDER_USE_INVALID_PATTERN_ERROR, - APPENDER_USE_MISSING_LAYOUT_ERROR, - APPENDER_USE_MISSING_WRITER_ERROR, - APPENDER_WRITING_FILE_ERROR, - // Level - LEVEL_INVALID_LEVEL_STRING, - // Layouts, PatternFormatter - LAYOUT_EXPECTED_DIGIT_ERROR, - LAYOUT_OPTION_IS_NOT_INTEGER_ERROR, - LAYOUT_INTEGER_IS_NOT_POSITIVE_ERROR, - // Logger - LOGGER_INVALID_LEVEL_FOR_ROOT, - // PropertyConfigurator, OptionHandler - CONFIGURATOR_OPENING_FILE_ERROR, - CONFIGURATOR_READING_FILE_ERROR, - CONFIGURATOR_INVALID_SUBSTITUTION_ERROR, - CONFIGURATOR_INVALID_OPTION_ERROR, - CONFIGURATOR_MISSING_APPENDER_ERROR, - CONFIGURATOR_UNKNOWN_APPENDER_CLASS_ERROR, - CONFIGURATOR_MISSING_LAYOUT_ERROR, - CONFIGURATOR_UNKNOWN_LAYOUT_CLASS_ERROR, - CONFIGURATOR_PROPERTY_ERROR, - CONFIGURATOR_UNKNOWN_TYPE_ERROR - }; - - - /****************************************************************************** - * Operators, Helpers - ******************************************************************************/ - - - /****************************************************************************** - * Inline - ******************************************************************************/ - - -} // namespace Log4Qt - - -#endif // LOG4QT_H diff --git a/src/log4qt/src/log4qt/log4qt.pri b/src/log4qt/src/log4qt/log4qt.pri deleted file mode 100644 index f9730b9..0000000 --- a/src/log4qt/src/log4qt/log4qt.pri +++ /dev/null @@ -1,111 +0,0 @@ -# ******************************************************************************* -# -# package: Log4Qt -# file: log4qt.pri -# created: September 2007 -# author: Martin Heinrich -# -# -# Copyright 2007 Martin Heinrich -# -# 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. -# -# ******************************************************************************* - -INCLUDEPATH += $$PWD/.. -DEPENDPATH += $$PWD/.. -HEADERS += \ - $$PWD/appender.h \ - $$PWD/appenderskeleton.h \ - $$PWD/basicconfigurator.h \ - $$PWD/consoleappender.h \ - $$PWD/dailyrollingfileappender.h \ - $$PWD/fileappender.h \ - $$PWD/helpers/classlogger.h \ - $$PWD/helpers/configuratorhelper.h \ - $$PWD/helpers/datetime.h \ - $$PWD/helpers/factory.h \ - $$PWD/helpers/initialisationhelper.h \ - $$PWD/helpers/logerror.h \ - $$PWD/helpers/logobject.h \ - $$PWD/helpers/logobjectptr.h \ - $$PWD/helpers/optionconverter.h \ - $$PWD/helpers/patternformatter.h \ - $$PWD/helpers/properties.h \ - $$PWD/hierarchy.h \ - $$PWD/layout.h \ - $$PWD/level.h \ - $$PWD/log4qt.h \ - $$PWD/logger.h \ - $$PWD/loggerrepository.h \ - $$PWD/loggingevent.h \ - $$PWD/logmanager.h \ - $$PWD/mdc.h \ - $$PWD/ndc.h \ - $$PWD/patternlayout.h \ - $$PWD/propertyconfigurator.h \ - $$PWD/rollingfileappender.h \ - $$PWD/simplelayout.h \ - $$PWD/spi/filter.h \ - $$PWD/ttcclayout.h \ - $$PWD/writerappender.h \ - $$PWD/varia/debugappender.h \ - $$PWD/varia/denyallfilter.h \ - $$PWD/varia/nullappender.h \ - $$PWD/varia/levelmatchfilter.h \ - $$PWD/varia/levelrangefilter.h \ - $$PWD/varia/listappender.h \ - $$PWD/varia/stringmatchfilter.h - -SOURCES += \ - $$PWD/appenderskeleton.cpp \ - $$PWD/basicconfigurator.cpp \ - $$PWD/consoleappender.cpp \ - $$PWD/dailyrollingfileappender.cpp \ - $$PWD/fileappender.cpp \ - $$PWD/helpers/classlogger.cpp \ - $$PWD/helpers/configuratorhelper.cpp \ - $$PWD/helpers/datetime.cpp \ - $$PWD/helpers/factory.cpp \ - $$PWD/helpers/initialisationhelper.cpp \ - $$PWD/helpers/logerror.cpp \ - $$PWD/helpers/logobject.cpp \ - $$PWD/helpers/logobjectptr.cpp \ - $$PWD/helpers/optionconverter.cpp \ - $$PWD/helpers/patternformatter.cpp \ - $$PWD/helpers/properties.cpp \ - $$PWD/hierarchy.cpp \ - $$PWD/layout.cpp \ - $$PWD/level.cpp \ - $$PWD/log4qt.cpp \ - $$PWD/logger.cpp \ - $$PWD/loggerrepository.cpp \ - $$PWD/loggingevent.cpp \ - $$PWD/logmanager.cpp \ - $$PWD/mdc.cpp \ - $$PWD/ndc.cpp \ - $$PWD/patternlayout.cpp \ - $$PWD/propertyconfigurator.cpp \ - $$PWD/rollingfileappender.cpp \ - $$PWD/simplelayout.cpp \ - $$PWD/spi/filter.cpp \ - $$PWD/ttcclayout.cpp \ - $$PWD/writerappender.cpp \ - $$PWD/varia/debugappender.cpp \ - $$PWD/varia/denyallfilter.cpp \ - $$PWD/varia/nullappender.cpp \ - $$PWD/varia/levelmatchfilter.cpp \ - $$PWD/varia/levelrangefilter.cpp \ - $$PWD/varia/listappender.cpp \ - $$PWD/varia/stringmatchfilter.cpp - \ No newline at end of file diff --git a/src/log4qt/src/log4qt/logger.cpp b/src/log4qt/src/log4qt/logger.cpp deleted file mode 100644 index d5dc936..0000000 --- a/src/log4qt/src/log4qt/logger.cpp +++ /dev/null @@ -1,349 +0,0 @@ -/****************************************************************************** - * - * package: Log4Qt - * file: logger.cpp - * created: September 2007 - * author: Martin Heinrich - * - * - * changes: Sep 2008, Martin Heinrich: - * - Fixed problem in Qt 4.4 where QReadWriteLock is by default - * non-recursive. - * - * - * Copyright 2007 - 2008 Martin Heinrich - * - * 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. - * - ******************************************************************************/ - - - -/****************************************************************************** - * Dependencies - ******************************************************************************/ - - -#include "log4qt/logger.h" - -#include -#include "log4qt/appenderskeleton.h" -#include "log4qt/varia/listappender.h" -#include "log4qt/loggingevent.h" -#include "log4qt/log4qt.h" -#include "log4qt/loggerrepository.h" -#include "log4qt/logmanager.h" - - -namespace Log4Qt -{ - - - /************************************************************************** - * Declarations - **************************************************************************/ - - - - /************************************************************************** - * C helper functions - **************************************************************************/ - - - - /************************************************************************** - * Class implementation: Logger - **************************************************************************/ - - - Logger::Logger(LoggerRepository* pLoggerRepository, Level level, const QString &rName, Logger *pParent) : - QObject(0), -#if QT_VERSION < QT_VERSION_CHECK(4, 4, 0) - mObjectGuard(), -#else - mObjectGuard(QReadWriteLock::Recursive), -#endif - mName(rName), - mpLoggerRepository(pLoggerRepository), - mAdditivity(true), - mAppenders(), - mLevel(level), - mpParent(pParent) - { - Q_ASSERT_X(pLoggerRepository, "Logger::Logger()", "Construction of Logger with null LoggerRepository"); - - setObjectName(mName); - } - - - Logger::~Logger() - { - logger()->warn("Unexpected destruction of Logger"); - - // QWriteLocker locker(&mObjectGuard); - // - // QMutableListIterator< LogObjectPtr > i(mAppenders); - // while (i.hasNext()) - // { - // i.next(); - // i.remove(); - // } - } - - - QList Logger::appenders() const - { - QReadLocker locker(&mObjectGuard); - - QList result; - Appender *p_appender; - Q_FOREACH(p_appender, mAppenders) - result << p_appender; - return result; - } - - - void Logger::setLevel(Level level) - { - // QWriteLocker locker(&mObjectGuard); // Read/Write int is safe - - if ((parentLogger() == 0) && (level == Level::NULL_INT)) - { - logger()->warn("Invalid root logger level NULL_INT. Using DEBUG_INT instead"); - level = Level::DEBUG_INT; - } - mLevel = level; - } - - - void Logger::addAppender(Appender *pAppender) - { - // Avoid deadlock: - // - Handle warnings, before write lock is aquired - - // Keep objects with a 0 reference count safe - LogObjectPtr p_appender = pAppender; - - { - QReadLocker locker(&mObjectGuard); - - if(!p_appender) - { - logger()->warn("Adding null Appender to Logger '%1'", name()); - return; - } - if(mAppenders.contains(p_appender)) - { - logger()->warn("Adding of duplicate appender '%2' to logger '%1'", name(), p_appender->name()); - return; - } - } - { - QWriteLocker locker(&mObjectGuard); - - if(mAppenders.contains(p_appender)) - return; - mAppenders.append(p_appender); - } - } - - - Appender *Logger::appender(const QString &rName) const - { - QReadLocker locker(&mObjectGuard); - - Appender *p_appender; - Q_FOREACH(p_appender, mAppenders) - if (p_appender->name() == rName) - return p_appender; - return 0; - } - - - - void Logger::callAppenders(const LoggingEvent &rEvent) const - { - QReadLocker locker(&mObjectGuard); - - Appender *p_appender; - Q_FOREACH(p_appender, mAppenders) - p_appender->doAppend(rEvent); - if (additivity() && (parentLogger() != 0)) - parentLogger()->callAppenders(rEvent); - } - - - bool Logger::isAttached(Appender *pAppender) const - { - QReadLocker locker(&mObjectGuard); - - // Keep objects with a 0 reference count safe - LogObjectPtr p_appender = pAppender; - - return mAppenders.contains(p_appender); - } - - - void Logger::removeAllAppenders() - { - // Avoid deadlock: - // - Only log warnings without having the write log aquired - // - Hold a reference to all appenders so that the remove does not - // destruct the appender over the reference count while the write - // log is held. The appender may log messages. - - logger()->trace("Removing all appenders from logger '%1'", name()); - - QList< LogObjectPtr > appenders; - { - QWriteLocker locker(&mObjectGuard); - QMutableListIterator< LogObjectPtr > i(mAppenders); - while (i.hasNext()) - { - Appender *p_appender = i.next(); - ListAppender *p_listappender = qobject_cast(p_appender); - if (p_listappender && p_listappender->configuratorList()) - continue; - else - { - appenders << p_appender; - i.remove(); - } - } - } - appenders.clear(); - } - - - void Logger::removeAppender(Appender *pAppender) - { - // Avoid deadlock: - // - Only log warnings without having the write log aquired - // - Hold a reference to the appender so that the remove does not - // destruct the appender over the reference count while the write - // log is held. The appender may log messages. - - LogObjectPtr p_appender = pAppender; - - if(!p_appender) - { - logger()->warn("Request to remove null Appender from Logger '%1'", name()); - return; - } - int n; - { - QWriteLocker locker(&mObjectGuard); - - n = mAppenders.removeAll(p_appender); - } - if (n == 0) - { - logger()->warn("Request to remove Appender '%2', which is not part of Logger '%1' appenders", name(), p_appender->name()); - return; - } - } - - - void Logger::removeAppender(const QString &rName) - { - Appender *p_appender = appender(rName); - if (p_appender) - removeAppender(p_appender); - } - - - Level Logger::effectiveLevel() const - { - Q_ASSERT_X(LogManager::rootLogger()->level() != Level::NULL_INT, "Logger::effectiveLevel()", "Root logger level must not be NULL_INT"); - - QReadLocker locker(&mObjectGuard); - - const Logger *p_logger = this; - while (p_logger->level() == Level::NULL_INT) - p_logger = p_logger->parentLogger(); - return p_logger->level(); - } - - - bool Logger::isEnabledFor(Level level) const - { - if (mpLoggerRepository->isDisabled(level)) - return false; - return (effectiveLevel() <= level); - } - - - Logger *Logger::logger(const QString &rName) - { - return LogManager::logger(rName); - } - - - Logger *Logger::logger(const char *pName) - { - return LogManager::logger(QLatin1String(pName)); - } - - - Logger *Logger::rootLogger() - { - return LogManager::rootLogger(); - } - - -#ifndef QT_NO_DEBUG_STREAM - QDebug Logger::debug(QDebug &rDebug) const - { - QReadLocker locker(&mObjectGuard); - - QString parent_logger; - if (mpParent) - parent_logger = mpParent->name(); - - rDebug.nospace() << "Logger(" - << "name:" << name() << " " - << "appenders:" << mAppenders.count() << " " - << "additivity:" << mAdditivity << " " - << mLevel - << "parentLogger:" << parent_logger - << ")"; - return rDebug.space(); - } -#endif // QT_NO_DEBUG_STREAM - - - void Logger::forcedLog(Level level, const QString &rMessage) const - { - QReadLocker locker(&mObjectGuard); - - LoggingEvent event(this, level, rMessage); - callAppenders(event); - } - - - - /************************************************************************** - * Implementation: Operators, Helper - **************************************************************************/ - - -#ifndef QT_NO_DEBUG_STREAM - QDebug operator<<(QDebug debug, const Logger &rLogger) - { - return rLogger.debug(debug); - } -#endif // QT_NO_DEBUG_STREAM - - - -} // namespace Log4Qt diff --git a/src/log4qt/src/log4qt/logger.h b/src/log4qt/src/log4qt/logger.h deleted file mode 100644 index 1b58adc..0000000 --- a/src/log4qt/src/log4qt/logger.h +++ /dev/null @@ -1,1665 +0,0 @@ -/****************************************************************************** - * - * package: Log4Qt - * file: logger.h - * created: September 2007 - * author: Martin Heinrich - * - * - * changes: Sep 2008, Martin Heinrich: - * - Replaced usage of q_atomic_test_and_set_ptr with - * QBasicAtomicPointer - * - * - * Copyright 2007 - 2008 Martin Heinrich - * - * 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. - * - ******************************************************************************/ - -#ifndef LOG4QT_LOGGER_H -#define LOG4QT_LOGGER_H - - -/****************************************************************************** - * Dependencies - ******************************************************************************/ - -#include - -#include -#include -#include -#include "log4qt/helpers/logerror.h" -#include "log4qt/helpers/classlogger.h" -#include "log4qt/helpers/logobjectptr.h" -#include "log4qt/level.h" - -#if QT_VERSION >= QT_VERSION_CHECK(4, 4, 0) -# ifndef Q_ATOMIC_POINTER_TEST_AND_SET_IS_ALWAYS_NATIVE -# warning "QAtomicPointer test and set is not native. The macro Log4Qt::LOG4QT_DECLARE_STATIC_LOGGER is not thread-safe." -# endif -#endif - - -/****************************************************************************** - * Declarations - ******************************************************************************/ - -namespace Log4Qt -{ - - /*! - * LOG4QT_DECLARE_STATIC_LOGGER declares a static function \a FUNCTION that - * returns a pointer to a \ref Log4Qt::Logger "Logger" named after \a CLASS. - * - * On the first invocation the \ref Log4Qt::Logger "Logger" is requested - * by calling \ref Log4Qt::Logger::logger(const char *pName) - * "Logger::logger( #CLASS )". The pointer is stored to be returned on - * subsequent invocations. - * - * The following example shows how to use the macro to define a logger to be - * used within a class not derived from QObject. - * - * \code - * #file: counter.h - * - * #include logger.h - * - * class Counter - * { - * public: - * Counter(); - * Counter(int preset); - * private: - * int mCount; - * } - * \endcode - * \code - * #file: counter.cpp - * - * #include counter.h - * - * LOG4QT_DECLARE_STATIC_LOGGER(logger, Counter) - * - * Counter::Counter() : - * mCount(0) - * {} - * - * void Counter::Counter(int preset) : - * mCount(preset) - * { - * if (preset < 0) - * { - * logger()->warn("Invalid negative counter preset %1. Using 0 instead.", preset); - * mCount = 0; - * } - * } - * \endcode - * - * \note The function created by the macro is thread-safe. - * - * \sa \ref Log4Qt::Logger::logger(const char *pName) "Logger::logger(const char *pName)" - */ -#if QT_VERSION < QT_VERSION_CHECK(4, 4, 0) - #define LOG4QT_DECLARE_STATIC_LOGGER(FUNCTION, CLASS) \ - static Log4Qt::Logger *FUNCTION() \ - { \ - static Log4Qt::Logger *p_logger = 0; \ - if (!p_logger) \ - { \ - q_atomic_test_and_set_ptr( \ - &p_logger, \ - 0, \ - Log4Qt::Logger::logger( #CLASS )); \ - } \ - return p_logger; \ - } -#elif QT_VERSION < QT_VERSION_CHECK(5, 0, 0) - #define LOG4QT_DECLARE_STATIC_LOGGER(FUNCTION, CLASS) \ - static Log4Qt::Logger *FUNCTION() \ - { \ - static QBasicAtomicPointer p_logger = \ - Q_BASIC_ATOMIC_INITIALIZER(0); \ - if (!p_logger) \ - { \ - p_logger.testAndSetOrdered(0, \ - Log4Qt::Logger::logger( #CLASS )); \ - } \ - return p_logger; \ - } -#else - #define LOG4QT_DECLARE_STATIC_LOGGER(FUNCTION, CLASS) \ - static Log4Qt::Logger *FUNCTION() \ - { \ - static QBasicAtomicPointer p_logger = \ - Q_BASIC_ATOMIC_INITIALIZER(0); \ - if (!p_logger.loadAcquire()) \ - { \ - p_logger.testAndSetOrdered(0, \ - Log4Qt::Logger::logger( #CLASS )); \ - } \ - return p_logger.loadAcquire(); \ - } -#endif - - /*! - * LOG4QT_DECLARE_QCLASS_LOGGER declares member functions to retrieve - * \ref Log4Qt::Logger "Logger" for the class it is used in. - * - * On the first invocation the \ref Log4Qt::Logger "Logger" is requested - * by a call to \ref Log4Qt::Logger::logger(const char *pName) - * "Logger::logger(const char *pName)". The pointer is stored to be - * returned on subsequent invocations. - * - * The following example shows how to use the macro to define a logger to be - * used within a class derived from QObject. - * - * \code - * #file: counter.h - * - * #include qobject.h - * #include logger.h - * - * class Counter : public QObject - * { - * Q_OBJECT - * LOG4QT_DECLARE_QCLASS_LOGGER - * public: - * Counter(); - * Counter(int preset); - * private: - * int mCount; - * } - * \endcode - * \code - * #file: counter.cpp - * - * #include counter.h - * - * Counter::Counter() : - * mCount(0) - * {} - * - * void Counter::Counter(int preset) - * mCount(preset) - * { - * if (preset < 0) - * { - * logger()->warn("Invalid negative counter preset %1. Using 0 instead.", preset); - * mCount = 0; - * } - * } - * \endcode - * - * \note The function created by the macro is thread-safe. - * - * \sa \ref Log4Qt::Logger::logger(const char *pName) "Logger::logger(const char *pName)", - * \ref Log4Qt::ClassLogger "ClassLogger" - */ - #define LOG4QT_DECLARE_QCLASS_LOGGER \ - private: \ - mutable Log4Qt::ClassLogger mLog4QtClassLogger; \ - public: \ - inline Log4Qt::Logger *logger() const \ - { return mLog4QtClassLogger.logger(this); } \ - private: - - class Appender; - class LoggingEvent; - class LoggerRepository; - - /*! - * \brief The class Logger provides logging services. - * - * A pointer to a logger can be retrieved by calling Logger::logger() or - * LogManager::logger() with the class name as argument. Because a logger - * is never destroyed it is possible to store the pointer to the logger. - * This way the lookup of the pointer in the repository is only required - * on the first logging operation. The macros \ref - * Log4Qt::LOG4QT_DECLARE_STATIC_LOGGER "LOG4QT_DECLARE_STATIC_LOGGER" and - * \ref Log4Qt::LOG4QT_DECLARE_QCLASS_LOGGER "LOG4QT_DECLARE_QCLASS_LOGGER" - * provide a thread-safe implementation to store the logger pointer. - * - * \note All the functions declared in this class are thread-safe. - */ - class Logger : public QObject - { - Q_OBJECT - - /*! - * The property holds, if the logger is additive. - * - * The default is true for being additive. - * - * \sa additive(), setAdditive() - */ - Q_PROPERTY(bool additivity READ additivity WRITE setAdditivity) - - /*! - * The property holds the level used by the logger. - * - * The default is Level::NULL_INT. - * \sa level(), setLevel() - */ - Q_PROPERTY(Level level READ level WRITE setLevel) - - /*! - * The property holds the LoggerRepository of the logger. - * - * \sa loggerRepository() - */ - Q_PROPERTY(LoggerRepository* loggerRepository READ loggerRepository) - - /*! - * The property holds the name of the logger. - * - * \sa name() - */ - Q_PROPERTY(QString name READ name) - - /*! - * The property holds the parent logger of the logger. - * - * \sa parentLogger() - */ - Q_PROPERTY(Logger* parentLogger READ parentLogger) - - LOG4QT_DECLARE_QCLASS_LOGGER - - protected: - Logger(LoggerRepository* pLoggerRepository, Level level, const QString &rName, Logger *pParent = 0); - virtual ~Logger(); - private: - Logger(const Logger &rOther); // Not implemented - Logger &operator=(const Logger &rOther); // Not implemented - - public: - bool additivity() const; - QList appenders() const; - Level level() const; - LoggerRepository *loggerRepository() const; - QString name() const; - Logger *parentLogger() const; - // JAVA: ResourceBundle *resourceBundle() const; - // JAVA: void setResourceBundle(ResourceBundle *pResourceBundle); - void setAdditivity(bool additivity); - virtual void setLevel(Level level); - - void addAppender(Appender *pAppender); - Appender *appender(const QString &rName) const; - void callAppenders(const LoggingEvent &rEvent) const; - bool isAttached(Appender *pAppender) const; - - /*! - * Removes all appenders that have been previously added from this - * Logger. - * - * To allow configurators to collect events during the configuration - * process ListAppenders with the configuratorList property set, will - * not be removed. - * - * \sa LisAppender::setConfiguratorList() - */ - void removeAllAppenders(); - - void removeAppender(Appender *pAppender); - void removeAppender(const QString &rName); - // JAVA: QString resourceBundleString(const QString &rKey) const; - - Level effectiveLevel() const; - bool isDebugEnabled() const; - - /*! - * Checks if this logger is enabled for a given Level \a level. If the - * logger is enabled the function returns true. Otherwise it returns - * false. - * - * A logger is enabled for a level, if the level is greater or equal - * then the repository threshold and greater and equal then the loggers - * effective level. - * - * \sa LoggerRepository::isDisabled(), effectiveLevel() - */ - bool isEnabledFor(Level level) const; - - bool isErrorEnabled() const; - bool isFatalEnabled() const; - bool isInfoEnabled() const; - bool isTraceEnabled() const; - bool isWarnEnabled() const; - - void debug(const QString &rMessage) const; - void debug(const LogError &rLogError) const; - void debug(const char *pMessage) const; - void debug(const char *pMessage, - const QString &rArg1) const; - void debug(const char *pMessage, - int arg1) const; - void debug(const char *pMessage, - const QString &rArg1, - const QString &rArg2) const; - void debug(const char *pMessage, - const QString &rArg1, - int arg2) const; - void debug(const char *pMessage, - int arg1, - const QString &rArg2) const; - void debug(const char *pMessage, - int arg1, - int arg2) const; - void debug(const char *pMessage, - const QString &rArg1, - const QString &rArg2, - const QString &rArg3) const; - void debug(const char *pMessage, - const QString &rArg1, - const QString &rArg2, - int arg3) const; - void debug(const char *pMessage, - const QString &rArg1, - int arg2, - const QString &rArg3) const; - void debug(const char *pMessage, - const QString &rArg1, - int arg2, - int arg3) const; - void debug(const char *pMessage, - int arg1, - const QString &rArg2, - const QString &rArg3) const; - void debug(const char *pMessage, - int arg1, - const QString &rArg2, - int arg3) const; - void debug(const char *pMessage, - int arg1, - int arg2, - const QString &rArg3) const; - void debug(const char *pMessage, - int arg1, - int arg2, - int arg3) const; - void debug(const char *pMessage, - const QVariant &rArg1, - const QVariant &rArg2, - const QVariant &rArg3) const; - - void error(const QString &rMessage) const; - void error(const LogError &rLogError) const; - void error(const char *pMessage) const; - void error(const char *pMessage, - const QString &rArg1) const; - void error(const char *pMessage, - int arg1) const; - void error(const char *pMessage, - const QString &rArg1, - const QString &rArg2) const; - void error(const char *pMessage, - const QString &rArg1, int arg2) const; - void error(const char *pMessage, - int arg1, - const QString &rArg2) const; - void error(const char *pMessage, - int arg1, - int arg2) const; - void error(const char *pMessage, - const QString &rArg1, - const QString &rArg2, - const QString &rArg3) const; - void error(const char *pMessage, - const QString &rArg1, - const QString &rArg2, - int arg3) const; - void error(const char *pMessage, - const QString &rArg1, - int arg2, - const QString &rArg3) const; - void error(const char *pMessage, - const QString &rArg1, - int arg2, - int arg3) const; - void error(const char *pMessage, - int arg1, - const QString &rArg2, - const QString &rArg3) const; - void error(const char *pMessage, - int arg1, - const QString &rArg2, - int arg3) const; - void error(const char *pMessage, - int arg1, - int arg2, - const QString &rArg3) const; - void error(const char *pMessage, - int arg1, - int arg2, - int arg3) const; - void error(const char *pMessage, - const QVariant &rArg1, - const QVariant &rArg2, - const QVariant &rArg3) const; - - void fatal(const QString &rMessage) const; - void fatal(const LogError &rLogError) const; - void fatal(const char *pMessage) const; - void fatal(const char *pMessage, - const QString &rArg1) const; - void fatal(const char *pMessage, - int arg1) const; - void fatal(const char *pMessage, - const QString &rArg1, - const QString &rArg2) const; - void fatal(const char *pMessage, - const QString &rArg1, - int arg2) const; - void fatal(const char *pMessage, - int arg1, - const QString &rArg2) const; - void fatal(const char *pMessage, - int arg1, - int arg2) const; - void fatal(const char *pMessage, - const QString &rArg1, - const QString &rArg2, - const QString &rArg3) const; - void fatal(const char *pMessage, - const QString &rArg1, - const QString &rArg2, - int arg3) const; - void fatal(const char *pMessage, - const QString &rArg1, - int arg2, - const QString &rArg3) const; - void fatal(const char *pMessage, - const QString &rArg1, - int arg2, - int arg3) const; - void fatal(const char *pMessage, - int arg1, - const QString &rArg2, - const QString &rArg3) const; - void fatal(const char *pMessage, - int arg1, - const QString &rArg2, - int arg3) const; - void fatal(const char *pMessage, - int arg1, - int arg2, - const QString &rArg3) const; - void fatal(const char *pMessage, - int arg1, - int arg2, - int arg3) const; - void fatal(const char *pMessage, - const QVariant &rArg1, - const QVariant &rArg2, - const QVariant &rArg3) const; - - void info(const QString &rMessage) const; - void info(const LogError &rLogError) const; - void info(const char *pMessage) const; - void info(const char *pMessage, - const QString &rArg1) const; - void info(const char *pMessage, - int arg1) const; - void info(const char *pMessage, - const QString &rArg1, - const QString &rArg2) const; - void info(const char *pMessage, - const QString &rArg1, - int arg2) const; - void info(const char *pMessage, - int arg1, - const QString &rArg2) const; - void info(const char *pMessage, - int arg1, - int arg2) const; - void info(const char *pMessage, - const QString &rArg1, - const QString &rArg2, - const QString &rArg3) const; - void info(const char *pMessage, - const QString &rArg1, - const QString &rArg2, - int arg3) const; - void info(const char *pMessage, - const QString &rArg1, - int arg2, - const QString &rArg3) const; - void info(const char *pMessage, - const QString &rArg1, - int arg2, - int arg3) const; - void info(const char *pMessage, - int arg1, - const QString &rArg2, - const QString &rArg3) const; - void info(const char *pMessage, - int arg1, - const QString &rArg2, - int arg3) const; - void info(const char *pMessage, - int arg1, - int arg2, - const QString &rArg3) const; - void info(const char *pMessage, - int arg1, - int arg2, - int arg3) const; - void info(const char *pMessage, - const QVariant &rArg1, - const QVariant &rArg2, - const QVariant &rArg3) const; - - void log(Level level, - const QString &rMessage) const; - void log(Level level, - const LogError &rLogError) const; - void log(Level level, - const char *pMessage) const; - void log(Level level, - const char *pMessage, - const QString &rArg1) const; - void log(Level level, - const char *pMessage, - int arg1) const; - void log(Level level, - const char *pMessage, - const QString &rArg1, - const QString &rArg2) const; - void log(Level level, - const char *pMessage, - const QString &rArg1, - int arg2) const; - void log(Level level, - const char *pMessage, - int arg1, - const QString &rArg2) const; - void log(Level level, - const char *pMessage, - int arg1, - int arg2) const; - void log(Level level, - const char *pMessage, - const QString &rArg1, - const QString &rArg2, - const QString &rArg3) const; - void log(Level level, - const char *pMessage, - const QString &rArg1, - const QString &rArg2, - int arg3) const; - void log(Level level, - const char *pMessage, - const QString &rArg1, - int arg2, - const QString &rArg3) const; - void log(Level level, - const char *pMessage, - const QString &rArg1, - int arg2, - int arg3) const; - void log(Level level, - const char *pMessage, - int arg1, - const QString &rArg2, - const QString &rArg3) const; - void log(Level level, - const char *pMessage, - int arg1, - const QString &rArg2, - int arg3) const; - void log(Level level, - const char *pMessage, - int arg1, - int arg2, - const QString &rArg3) const; - void log(Level level, - const char *pMessage, - int arg1, - int arg2, - int arg3) const; - void log(Level level, - const char *pMessage, - const QVariant &rArg1, - const QVariant &rArg2, - const QVariant &rArg3) const; - - // JAVA: void l7dlog(Level level, - // const QString &rKey); - // JAVA: void l7dlog(Level level, - // const QString &rKey, - // const QList rParameters); - - void trace(const QString &rMessage) const; - void trace(const LogError &rLogError) const; - void trace(const char *pMessage) const; - void trace(const char *pMessage, - const QString &rArg1) const; - void trace(const char *pMessage, - int arg1) const; - void trace(const char *pMessage, - const QString &rArg1, - const QString &rArg2) const; - void trace(const char *pMessage, - const QString &rArg1, - int arg2) const; - void trace(const char *pMessage, - int arg1, - const QString &rArg2) const; - void trace(const char *pMessage, - int arg1, - int arg2) const; - void trace(const char *pMessage, - const QString &rArg1, - const QString &rArg2, - const QString &rArg3) const; - void trace(const char *pMessage, - const QString &rArg1, - const QString &rArg2, - int arg3) const; - void trace(const char *pMessage, - const QString &rArg1, - int arg2, - const QString &rArg3) const; - void trace(const char *pMessage, - const QString &rArg1, - int arg2, - int arg3) const; - void trace(const char *pMessage, - int arg1, - const QString &rArg2, - const QString &rArg3) const; - void trace(const char *pMessage, - int arg1, - const QString &rArg2, - int arg3) const; - void trace(const char *pMessage, - int arg1, - int arg2, - const QString &rArg3) const; - void trace(const char *pMessage, - int arg1, - int arg2, - int arg3) const; - void trace(const char *pMessage, - const QVariant &rArg1, - const QVariant &rArg2, - const QVariant &rArg3) const; - - void warn(const QString &rMessage) const; - void warn(const LogError &rLogError) const; - void warn(const char *pMessage) const; - void warn(const char *pMessage, - const QString &rArg1) const; - void warn(const char *pMessage, - int arg1) const; - void warn(const char *pMessage, - const QString &rArg1, - const QString &rArg2) const; - void warn(const char *pMessage, - const QString &rArg1, - int arg2) const; - void warn(const char *pMessage, - int arg1, - const QString &rArg2) const; - void warn(const char *pMessage, - int arg1, - int arg2) const; - void warn(const char *pMessage, - const QString &rArg1, - const QString &rArg2, - const QString &rArg3) const; - void warn(const char *pMessage, - const QString &rArg1, - const QString &rArg2, - int arg3) const; - void warn(const char *pMessage, - const QString &rArg1, - int arg2, - const QString &rArg3) const; - void warn(const char *pMessage, - const QString &rArg1, - int arg2, - int arg3) const; - void warn(const char *pMessage, - int arg1, - const QString &rArg2, - const QString &rArg3) const; - void warn(const char *pMessage, - int arg1, - const QString &rArg2, - int arg3) const; - void warn(const char *pMessage, - int arg1, - int arg2, - const QString &rArg3) const; - void warn(const char *pMessage, - int arg1, - int arg2, - int arg3) const; - void warn(const char *pMessage, - const QVariant &rArg1, - const QVariant &rArg2, - const QVariant &rArg3) const; - - // LogManager operations - static Logger *logger(const QString &rName); - static Logger *logger(const char *pName); - static Logger *rootLogger(); - - protected: -#ifndef QT_NO_DEBUG_STREAM - /*! - * Writes all object member variables to the given debug stream \a rDebug - * and returns the stream. - * - * - * %Logger(name:"Log4Qt" appenders:0 additivity:true Level("NULL") - * parentLogger: "root" ) - * - * \sa QDebug, operator<<(QDebug debug, const Appender &rAppender) - */ - virtual QDebug debug(QDebug &rDebug) const; - friend QDebug operator<<(QDebug debug, - const Logger &rLogger); -#endif // QT_NO_DEBUG_STREAM - - void forcedLog(Level level, - const QString &rMessage) const; - - protected: - mutable QReadWriteLock mObjectGuard; - private: - const QString mName; - LoggerRepository* mpLoggerRepository; - volatile bool mAdditivity; - QList< LogObjectPtr > mAppenders; - Level mLevel; - Logger *mpParent; - - // Needs to be friend to create Logger objects - friend class Hierarchy; - }; - - - /****************************************************************************** - * Operators, Helper - ******************************************************************************/ - -#ifndef QT_NO_DEBUG_STREAM - /*! - * \relates Logger - * - * Writes all object member variables to the given debug stream \a debug and - * returns the stream. - * - * To handle subclassing the function uses the virtual member function debug(). - * This allows each class to generate its own output. - * - * \sa QDebug, debug() - */ - QDebug operator<<(QDebug debug, - const Logger &rLogger); -#endif // QT_NO_DEBUG_STREAM - - - /************************************************************************** - * Inline - **************************************************************************/ - - inline bool Logger::additivity() const - { // QReadLocker locker(&mObjectGuard); // Read/Write of int is safe - return mAdditivity; } - - inline Level Logger::level() const - { // QReadLocker locker(&mObjectGuard); // Level is thread-safe - return mLevel; } - - inline LoggerRepository *Logger::loggerRepository() const - { // QReadLocker locker(&mObjectGuard); // Constant for object lifetime - return mpLoggerRepository; } - - inline QString Logger::name() const - { // QReadLocker locker(&mObjectGuard); // Constant for object lifetime - return mName; } - - inline Logger *Logger::parentLogger() const - { // QReadLocker locker(&mObjectGuard); // Constant for object lifetime - return mpParent; } - - inline void Logger::setAdditivity(bool additivity) - { // QWriteLocker locker(&mObjectGuard); // Read/Write of int is safe - mAdditivity = additivity; } - - // Level operations - - inline bool Logger::isDebugEnabled() const - { return isEnabledFor(Level::DEBUG_INT); } - - inline bool Logger::isErrorEnabled() const - { return isEnabledFor(Level::ERROR_INT); } - - inline bool Logger::isFatalEnabled() const - { return isEnabledFor(Level::FATAL_INT); } - - inline bool Logger::isInfoEnabled() const - { return isEnabledFor(Level::INFO_INT); } - - inline bool Logger::isTraceEnabled() const - { return isEnabledFor(Level::TRACE_INT); } - - inline bool Logger::isWarnEnabled() const - { return isEnabledFor(Level::WARN_INT); } - - // Log operations: debug - - inline void Logger::debug(const LogError &rLogError) const - { if (isEnabledFor(Level::DEBUG_INT)) - forcedLog(Level::DEBUG_INT, rLogError.toString()); } - - inline void Logger::debug(const QString &rMessage) const - { if (isEnabledFor(Level::DEBUG_INT)) - forcedLog(Level::DEBUG_INT, rMessage); } - - inline void Logger::debug(const char *pMessage) const - { if (isEnabledFor(Level::DEBUG_INT)) - forcedLog(Level::DEBUG_INT, QString::fromUtf8(pMessage)); } - - inline void Logger::debug(const char *pMessage, - const QString &rArg1) const - { if (isEnabledFor(Level::DEBUG_INT)) - forcedLog(Level::DEBUG_INT, QString::fromUtf8(pMessage).arg(rArg1)); } - - inline void Logger::debug(const char *pMessage, - int arg1) const - { if (isEnabledFor(Level::DEBUG_INT)) - forcedLog(Level::DEBUG_INT, QString::fromUtf8(pMessage).arg(arg1)); } - - inline void Logger::debug(const char *pMessage, - const QString &rArg1, - const QString &rArg2) const - { if (isEnabledFor(Level::DEBUG_INT)) - forcedLog(Level::DEBUG_INT, QString::fromUtf8(pMessage).arg(rArg1, rArg2)); } - - inline void Logger::debug(const char *pMessage, - const QString &rArg1, - int arg2) const - { if (isEnabledFor(Level::DEBUG_INT)) - forcedLog(Level::DEBUG_INT, QString::fromUtf8(pMessage).arg(rArg1).arg(arg2)); } - - inline void Logger::debug(const char *pMessage, - int arg1, - const QString &rArg2) const - { if (isEnabledFor(Level::DEBUG_INT)) - forcedLog(Level::DEBUG_INT, QString::fromUtf8(pMessage).arg(arg1).arg(rArg2)); } - - inline void Logger::debug(const char *pMessage, - int arg1, - int arg2) const - { if (isEnabledFor(Level::DEBUG_INT)) - forcedLog(Level::DEBUG_INT, QString::fromUtf8(pMessage).arg(arg1).arg(arg2)); } - - inline void Logger::debug(const char *pMessage, - const QString &rArg1, - const QString &rArg2, - const QString &rArg3) const - { if (isEnabledFor(Level::DEBUG_INT)) - forcedLog(Level::DEBUG_INT, QString::fromUtf8(pMessage).arg(rArg1, rArg2, rArg3)); } - - inline void Logger::debug(const char *pMessage, - const QString &rArg1, - const QString &rArg2, - int arg3) const - { if (isEnabledFor(Level::DEBUG_INT)) - forcedLog(Level::DEBUG_INT, QString::fromUtf8(pMessage).arg(rArg1, rArg2).arg(arg3)); } - - inline void Logger::debug(const char *pMessage, - const QString &rArg1, - int arg2, - const QString &rArg3) const - { if (isEnabledFor(Level::DEBUG_INT)) - forcedLog(Level::DEBUG_INT, QString::fromUtf8(pMessage).arg(rArg1).arg(arg2).arg(rArg3)); } - - inline void Logger::debug(const char *pMessage, - const QString &rArg1, - int arg2, - int arg3) const - { if (isEnabledFor(Level::DEBUG_INT)) - forcedLog(Level::DEBUG_INT, QString::fromUtf8(pMessage).arg(rArg1).arg(arg2).arg(arg3)); } - - inline void Logger::debug(const char *pMessage, - int arg1, - const QString &rArg2, - const QString &rArg3) const - { if (isEnabledFor(Level::DEBUG_INT)) - forcedLog(Level::DEBUG_INT, QString::fromUtf8(pMessage).arg(arg1).arg(rArg2).arg(rArg3)); } - - inline void Logger::debug(const char *pMessage, - int arg1, - const QString &rArg2, - int arg3) const - { if (isEnabledFor(Level::DEBUG_INT)) - forcedLog(Level::DEBUG_INT, QString::fromUtf8(pMessage).arg(arg1).arg(rArg2).arg(arg3)); } - - inline void Logger::debug(const char *pMessage, - int arg1, - int arg2, - const QString &rArg3) const - { if (isEnabledFor(Level::DEBUG_INT)) - forcedLog(Level::DEBUG_INT, QString::fromUtf8(pMessage).arg(arg1).arg(arg2).arg(rArg3)); } - - inline void Logger::debug(const char *pMessage, - int arg1, - int arg2, - int arg3) const - { if (isEnabledFor(Level::DEBUG_INT)) - forcedLog(Level::DEBUG_INT, QString::fromUtf8(pMessage).arg(arg1).arg(arg2).arg(arg3)); } - - inline void Logger::debug(const char *pMessage, - const QVariant &rArg1, - const QVariant &rArg2, - const QVariant &rArg3) const - { if (isEnabledFor(Level::DEBUG_INT)) - forcedLog(Level::DEBUG_INT, QString::fromUtf8(pMessage).arg(rArg1.toString(), rArg2.toString(), rArg3.toString())); } - - // Log operations: error - - inline void Logger::error(const QString &rMessage) const - { if (isEnabledFor(Level::ERROR_INT)) - forcedLog(Level::ERROR_INT, rMessage); } - - inline void Logger::error(const LogError &rLogError) const - { if (isEnabledFor(Level::ERROR_INT)) - forcedLog(Level::ERROR_INT, rLogError.toString()); } - - inline void Logger::error(const char *pMessage) const - { if (isEnabledFor(Level::ERROR_INT)) - forcedLog(Level::ERROR_INT, QString::fromUtf8(pMessage)); } - - inline void Logger::error(const char *pMessage, - const QString &rArg1) const - { if (isEnabledFor(Level::ERROR_INT)) - forcedLog(Level::ERROR_INT, QString::fromUtf8(pMessage).arg(rArg1)); } - - inline void Logger::error(const char *pMessage, - int arg1) const - { if (isEnabledFor(Level::ERROR_INT)) - forcedLog(Level::ERROR_INT, QString::fromUtf8(pMessage).arg(arg1)); } - - inline void Logger::error(const char *pMessage, - const QString &rArg1, - const QString &rArg2) const - { if (isEnabledFor(Level::ERROR_INT)) - forcedLog(Level::ERROR_INT, QString::fromUtf8(pMessage).arg(rArg1, rArg2)); } - - inline void Logger::error(const char *pMessage, - const QString &rArg1, - int arg2) const - { if (isEnabledFor(Level::ERROR_INT)) - forcedLog(Level::ERROR_INT, QString::fromUtf8(pMessage).arg(rArg1).arg(arg2)); } - - inline void Logger::error(const char *pMessage, - int arg1, - const QString &rArg2) const - { if (isEnabledFor(Level::ERROR_INT)) - forcedLog(Level::ERROR_INT, QString::fromUtf8(pMessage).arg(arg1).arg(rArg2)); } - - inline void Logger::error(const char *pMessage, - int arg1, - int arg2) const - { if (isEnabledFor(Level::ERROR_INT)) - forcedLog(Level::ERROR_INT, QString::fromUtf8(pMessage).arg(arg1).arg(arg2)); } - - inline void Logger::error(const char *pMessage, - const QString &rArg1, - const QString &rArg2, - const QString &rArg3) const - { if (isEnabledFor(Level::ERROR_INT)) - forcedLog(Level::ERROR_INT, QString::fromUtf8(pMessage).arg(rArg1, rArg2, rArg3)); } - - inline void Logger::error(const char *pMessage, - const QString &rArg1, - const QString &rArg2, - int arg3) const - { if (isEnabledFor(Level::ERROR_INT)) - forcedLog(Level::ERROR_INT, QString::fromUtf8(pMessage).arg(rArg1, rArg2).arg(arg3)); } - - inline void Logger::error(const char *pMessage, - const QString &rArg1, - int arg2, - const QString &rArg3) const - { if (isEnabledFor(Level::ERROR_INT)) - forcedLog(Level::ERROR_INT, QString::fromUtf8(pMessage).arg(rArg1).arg(arg2).arg(rArg3)); } - - inline void Logger::error(const char *pMessage, - const QString &rArg1, - int arg2, - int arg3) const - { if (isEnabledFor(Level::ERROR_INT)) - forcedLog(Level::ERROR_INT, QString::fromUtf8(pMessage).arg(rArg1).arg(arg2).arg(arg3)); } - - inline void Logger::error(const char *pMessage, - int arg1, - const QString &rArg2, - const QString &rArg3) const - { if (isEnabledFor(Level::ERROR_INT)) - forcedLog(Level::ERROR_INT, QString::fromUtf8(pMessage).arg(arg1).arg(rArg2).arg(rArg3)); } - - inline void Logger::error(const char *pMessage, - int arg1, - const QString &rArg2, - int arg3) const - { if (isEnabledFor(Level::ERROR_INT)) - forcedLog(Level::ERROR_INT, QString::fromUtf8(pMessage).arg(arg1).arg(rArg2).arg(arg3)); } - - inline void Logger::error(const char *pMessage, - int arg1, - int arg2, - const QString &rArg3) const - { if (isEnabledFor(Level::ERROR_INT)) - forcedLog(Level::ERROR_INT, QString::fromUtf8(pMessage).arg(arg1).arg(arg2).arg(rArg3)); } - - inline void Logger::error(const char *pMessage, - int arg1, - int arg2, - int arg3) const - { if (isEnabledFor(Level::ERROR_INT)) - forcedLog(Level::ERROR_INT, QString::fromUtf8(pMessage).arg(arg1).arg(arg2).arg(arg3)); } - - inline void Logger::error(const char *pMessage, - const QVariant &rArg1, - const QVariant &rArg2, - const QVariant &rArg3) const - { if (isEnabledFor(Level::ERROR_INT)) - forcedLog(Level::ERROR_INT, QString::fromUtf8(pMessage).arg(rArg1.toString(), rArg2.toString(), rArg3.toString())); } - - // Log operations: fatal - - inline void Logger::fatal(const QString &rMessage) const - { if (isEnabledFor(Level::FATAL_INT)) - forcedLog(Level::FATAL_INT, rMessage); } - - inline void Logger::fatal(const LogError &rLogError) const - { if (isEnabledFor(Level::FATAL_INT)) - forcedLog(Level::FATAL_INT, rLogError.toString()); } - - inline void Logger::fatal(const char *pMessage) const - { if (isEnabledFor(Level::FATAL_INT)) - forcedLog(Level::FATAL_INT, QString::fromUtf8(pMessage)); } - - inline void Logger::fatal(const char *pMessage, - const QString &rArg1) const - { if (isEnabledFor(Level::FATAL_INT)) - forcedLog(Level::FATAL_INT, QString::fromUtf8(pMessage).arg(rArg1)); } - - inline void Logger::fatal(const char *pMessage, - int arg1) const - { if (isEnabledFor(Level::FATAL_INT)) - forcedLog(Level::FATAL_INT, QString::fromUtf8(pMessage).arg(arg1)); } - - inline void Logger::fatal(const char *pMessage, - const QString &rArg1, const QString &rArg2) const - { if (isEnabledFor(Level::FATAL_INT)) - forcedLog(Level::FATAL_INT, QString::fromUtf8(pMessage).arg(rArg1, rArg2)); } - - inline void Logger::fatal(const char *pMessage, - const QString &rArg1, int arg2) const - { if (isEnabledFor(Level::FATAL_INT)) - forcedLog(Level::FATAL_INT, QString::fromUtf8(pMessage).arg(rArg1).arg(arg2)); } - - inline void Logger::fatal(const char *pMessage, - int arg1, - const QString &rArg2) const - { if (isEnabledFor(Level::FATAL_INT)) - forcedLog(Level::FATAL_INT, QString::fromUtf8(pMessage).arg(arg1).arg(rArg2)); } - - inline void Logger::fatal(const char *pMessage, - int arg1, - int arg2) const - { if (isEnabledFor(Level::FATAL_INT)) - forcedLog(Level::FATAL_INT, QString::fromUtf8(pMessage).arg(arg1).arg(arg2)); } - - inline void Logger::fatal(const char *pMessage, - const QString &rArg1, - const QString &rArg2, - const QString &rArg3) const - { if (isEnabledFor(Level::FATAL_INT)) - forcedLog(Level::FATAL_INT, QString::fromUtf8(pMessage).arg(rArg1, rArg2, rArg3)); } - - inline void Logger::fatal(const char *pMessage, - const QString &rArg1, - const QString &rArg2, - int arg3) const - { if (isEnabledFor(Level::FATAL_INT)) - forcedLog(Level::FATAL_INT, QString::fromUtf8(pMessage).arg(rArg1, rArg2).arg(arg3)); } - - inline void Logger::fatal(const char *pMessage, - const QString &rArg1, - int arg2, - const QString &rArg3) const - { if (isEnabledFor(Level::FATAL_INT)) - forcedLog(Level::FATAL_INT, QString::fromUtf8(pMessage).arg(rArg1).arg(arg2).arg(rArg3)); } - - inline void Logger::fatal(const char *pMessage, - const QString &rArg1, - int arg2, - int arg3) const - { if (isEnabledFor(Level::FATAL_INT)) - forcedLog(Level::FATAL_INT, QString::fromUtf8(pMessage).arg(rArg1).arg(arg2).arg(arg3)); } - - inline void Logger::fatal(const char *pMessage, - int arg1, - const QString &rArg2, - const QString &rArg3) const - { if (isEnabledFor(Level::FATAL_INT)) - forcedLog(Level::FATAL_INT, QString::fromUtf8(pMessage).arg(arg1).arg(rArg2).arg(rArg3)); } - - inline void Logger::fatal(const char *pMessage, - int arg1, - const QString &rArg2, - int arg3) const - { if (isEnabledFor(Level::FATAL_INT)) - forcedLog(Level::FATAL_INT, QString::fromUtf8(pMessage).arg(arg1).arg(rArg2).arg(arg3)); } - - inline void Logger::fatal(const char *pMessage, - int arg1, - int arg2, - const QString &rArg3) const - { if (isEnabledFor(Level::FATAL_INT)) - forcedLog(Level::FATAL_INT, QString::fromUtf8(pMessage).arg(arg1).arg(arg2).arg(rArg3)); } - - inline void Logger::fatal(const char *pMessage, - int arg1, - int arg2, - int arg3) const - { if (isEnabledFor(Level::FATAL_INT)) - forcedLog(Level::FATAL_INT, QString::fromUtf8(pMessage).arg(arg1).arg(arg2).arg(arg3)); } - - inline void Logger::fatal(const char *pMessage, - const QVariant &rArg1, - const QVariant &rArg2, - const QVariant &rArg3) const - { if (isEnabledFor(Level::FATAL_INT)) - forcedLog(Level::FATAL_INT, QString::fromUtf8(pMessage).arg(rArg1.toString(), rArg2.toString(), rArg3.toString())); } - - // Log operations: info - - inline void Logger::info(const QString &rMessage) const - { if (isEnabledFor(Level::INFO_INT)) - forcedLog(Level::INFO_INT, rMessage); } - - inline void Logger::info(const LogError &rLogError) const - { if (isEnabledFor(Level::INFO_INT)) - forcedLog(Level::INFO_INT, rLogError.toString()); } - - inline void Logger::info(const char *pMessage) const - { if (isEnabledFor(Level::INFO_INT)) - forcedLog(Level::INFO_INT, QString::fromUtf8(pMessage)); } - - inline void Logger::info(const char *pMessage, - const QString &rArg1) const - { if (isEnabledFor(Level::INFO_INT)) - forcedLog(Level::INFO_INT, QString::fromUtf8(pMessage).arg(rArg1)); } - - inline void Logger::info(const char *pMessage, - int arg1) const - { if (isEnabledFor(Level::INFO_INT)) - forcedLog(Level::INFO_INT, QString::fromUtf8(pMessage).arg(arg1)); } - - inline void Logger::info(const char *pMessage, - const QString &rArg1, - const QString &rArg2) const - { if (isEnabledFor(Level::INFO_INT)) - forcedLog(Level::INFO_INT, QString::fromUtf8(pMessage).arg(rArg1, rArg2)); } - - inline void Logger::info(const char *pMessage, - const QString &rArg1, - int arg2) const - { if (isEnabledFor(Level::INFO_INT)) - forcedLog(Level::INFO_INT, QString::fromUtf8(pMessage).arg(rArg1).arg(arg2)); } - - inline void Logger::info(const char *pMessage, - int arg1, - const QString &rArg2) const - { if (isEnabledFor(Level::INFO_INT)) - forcedLog(Level::INFO_INT, QString::fromUtf8(pMessage).arg(arg1).arg(rArg2)); } - - inline void Logger::info(const char *pMessage, - int arg1, - int arg2) const - { if (isEnabledFor(Level::INFO_INT)) - forcedLog(Level::INFO_INT, QString::fromUtf8(pMessage).arg(arg1).arg(arg2)); } - - inline void Logger::info(const char *pMessage, - const QString &rArg1, - const QString &rArg2, - const QString &rArg3) const - { if (isEnabledFor(Level::INFO_INT)) - forcedLog(Level::INFO_INT, QString::fromUtf8(pMessage).arg(rArg1, rArg2, rArg3)); } - - inline void Logger::info(const char *pMessage, - const QString &rArg1, - const QString &rArg2, - int arg3) const - { if (isEnabledFor(Level::INFO_INT)) - forcedLog(Level::INFO_INT, QString::fromUtf8(pMessage).arg(rArg1, rArg2).arg(arg3)); } - - inline void Logger::info(const char *pMessage, - const QString &rArg1, - int arg2, - const QString &rArg3) const - { if (isEnabledFor(Level::INFO_INT)) - forcedLog(Level::INFO_INT, QString::fromUtf8(pMessage).arg(rArg1).arg(arg2).arg(rArg3)); } - - inline void Logger::info(const char *pMessage, - const QString &rArg1, - int arg2, - int arg3) const - { if (isEnabledFor(Level::INFO_INT)) - forcedLog(Level::INFO_INT, QString::fromUtf8(pMessage).arg(rArg1).arg(arg2).arg(arg3)); } - - inline void Logger::info(const char *pMessage, - int arg1, - const QString &rArg2, - const QString &rArg3) const - { if (isEnabledFor(Level::INFO_INT)) - forcedLog(Level::INFO_INT, QString::fromUtf8(pMessage).arg(arg1).arg(rArg2).arg(rArg3)); } - - inline void Logger::info(const char *pMessage, - int arg1, - const QString &rArg2, - int arg3) const - { if (isEnabledFor(Level::INFO_INT)) - forcedLog(Level::INFO_INT, QString::fromUtf8(pMessage).arg(arg1).arg(rArg2).arg(arg3)); } - - inline void Logger::info(const char *pMessage, - int arg1, - int arg2, - const QString &rArg3) const - { if (isEnabledFor(Level::INFO_INT)) - forcedLog(Level::INFO_INT, QString::fromUtf8(pMessage).arg(arg1).arg(arg2).arg(rArg3)); } - - inline void Logger::info(const char *pMessage, - int arg1, - int arg2, - int arg3) const - { if (isEnabledFor(Level::INFO_INT)) - forcedLog(Level::INFO_INT, QString::fromUtf8(pMessage).arg(arg1).arg(arg2).arg(arg3)); } - - inline void Logger::info(const char *pMessage, - const QVariant &rArg1, - const QVariant &rArg2, - const QVariant &rArg3) const - { if (isEnabledFor(Level::INFO_INT)) - forcedLog(Level::INFO_INT, QString::fromUtf8(pMessage).arg(rArg1.toString(), rArg2.toString(), rArg3.toString())); } - - // Log operations: log - - inline void Logger::log(Level level, - const QString &rMessage) const - { if (isEnabledFor(level)) - forcedLog(level, rMessage); } - - inline void Logger::log(Level level, - const LogError &rLogError) const - { if (isEnabledFor(level)) - forcedLog(level, rLogError.toString()); } - - inline void Logger::log(Level level, - const char *pMessage) const - { if (isEnabledFor(level)) - forcedLog(level, QString::fromUtf8(pMessage)); } - - inline void Logger::log(Level level, - const char *pMessage, - const QString &rArg1) const - { if (isEnabledFor(level)) - forcedLog(level, QString::fromUtf8(pMessage).arg(rArg1)); } - - inline void Logger::log(Level level, - const char *pMessage, - int arg1) const - { if (isEnabledFor(level)) - forcedLog(level, QString::fromUtf8(pMessage).arg(arg1)); } - - inline void Logger::log(Level level, - const char *pMessage, - const QString &rArg1, - const QString &rArg2) const - { if (isEnabledFor(level)) - forcedLog(level, QString::fromUtf8(pMessage).arg(rArg1, rArg2)); } - - inline void Logger::log(Level level, - const char *pMessage, - const QString &rArg1, int arg2) const - { if (isEnabledFor(level)) - forcedLog(level, QString::fromUtf8(pMessage).arg(rArg1).arg(arg2)); } - - inline void Logger::log(Level level, - const char *pMessage, - int arg1, - const QString &rArg2) const - { if (isEnabledFor(level)) - forcedLog(level, QString::fromUtf8(pMessage).arg(arg1).arg(rArg2)); } - - inline void Logger::log(Level level, - const char *pMessage, - int arg1, - int arg2) const - { if (isEnabledFor(level)) - forcedLog(level, QString::fromUtf8(pMessage).arg(arg1).arg(arg2)); } - - inline void Logger::log(Level level, - const char *pMessage, - const QString &rArg1, - const QString &rArg2, - const QString &rArg3) const - { if (isEnabledFor(level)) - forcedLog(level, QString::fromUtf8(pMessage).arg(rArg1, rArg2, rArg3)); } - - inline void Logger::log(Level level, - const char *pMessage, - const QString &rArg1, - const QString &rArg2, - int arg3) const - { if (isEnabledFor(level)) - forcedLog(level, QString::fromUtf8(pMessage).arg(rArg1, rArg2).arg(arg3)); } - - inline void Logger::log(Level level, - const char *pMessage, - const QString &rArg1, - int arg2, - const QString &rArg3) const - { if (isEnabledFor(level)) - forcedLog(level, QString::fromUtf8(pMessage).arg(rArg1).arg(arg2).arg(rArg3)); } - - inline void Logger::log(Level level, - const char *pMessage, - const QString &rArg1, - int arg2, - int arg3) const - { if (isEnabledFor(level)) - forcedLog(level, QString::fromUtf8(pMessage).arg(rArg1).arg(arg2).arg(arg3)); } - - inline void Logger::log(Level level, - const char *pMessage, - int arg1, - const QString &rArg2, - const QString &rArg3) const - { if (isEnabledFor(level)) - forcedLog(level, QString::fromUtf8(pMessage).arg(arg1).arg(rArg2).arg(rArg3)); } - - inline void Logger::log(Level level, - const char *pMessage, - int arg1, - const QString &rArg2, - int arg3) const - { if (isEnabledFor(level)) - forcedLog(level, QString::fromUtf8(pMessage).arg(arg1).arg(rArg2).arg(arg3)); } - - inline void Logger::log(Level level, - const char *pMessage, - int arg1, - int arg2, - const QString &rArg3) const - { if (isEnabledFor(level)) - forcedLog(level, QString::fromUtf8(pMessage).arg(arg1).arg(arg2).arg(rArg3)); } - - inline void Logger::log(Level level, - const char *pMessage, - int arg1, - int arg2, - int arg3) const - { if (isEnabledFor(level)) - forcedLog(level, QString::fromUtf8(pMessage).arg(arg1).arg(arg2).arg(arg3)); } - - inline void Logger::log(Level level, - const char *pMessage, - const QVariant &rArg1, - const QVariant &rArg2, - const QVariant &rArg3) const - { if (isEnabledFor(level)) - forcedLog(level, QString::fromUtf8(pMessage).arg(rArg1.toString(), rArg2.toString(), rArg3.toString())); } - - // Log operations: trace - - inline void Logger::trace(const QString &rMessage) const - { if (isEnabledFor(Level::TRACE_INT)) - forcedLog(Level::TRACE_INT, rMessage); } - - inline void Logger::trace(const LogError &rLogError) const - { if (isEnabledFor(Level::TRACE_INT)) - forcedLog(Level::TRACE_INT, rLogError.toString()); } - - inline void Logger::trace(const char *pMessage) const - { if (isEnabledFor(Level::TRACE_INT)) - forcedLog(Level::TRACE_INT, QString::fromUtf8(pMessage)); } - - inline void Logger::trace(const char *pMessage, - const QString &rArg1) const - { if (isEnabledFor(Level::TRACE_INT)) - forcedLog(Level::TRACE_INT, QString::fromUtf8(pMessage).arg(rArg1)); } - - inline void Logger::trace(const char *pMessage, - int arg1) const - { if (isEnabledFor(Level::TRACE_INT)) - forcedLog(Level::TRACE_INT, QString::fromUtf8(pMessage).arg(arg1)); } - - inline void Logger::trace(const char *pMessage, - const QString &rArg1, - const QString &rArg2) const - { if (isEnabledFor(Level::TRACE_INT)) - forcedLog(Level::TRACE_INT, QString::fromUtf8(pMessage).arg(rArg1, rArg2)); } - - inline void Logger::trace(const char *pMessage, - const QString &rArg1, - int arg2) const - { if (isEnabledFor(Level::TRACE_INT)) - forcedLog(Level::TRACE_INT, QString::fromUtf8(pMessage).arg(rArg1).arg(arg2)); } - - inline void Logger::trace(const char *pMessage, - int arg1, - const QString &rArg2) const - { if (isEnabledFor(Level::TRACE_INT)) - forcedLog(Level::TRACE_INT, QString::fromUtf8(pMessage).arg(arg1).arg(rArg2)); } - - inline void Logger::trace(const char *pMessage, - int arg1, - int arg2) const - { if (isEnabledFor(Level::TRACE_INT)) - forcedLog(Level::TRACE_INT, QString::fromUtf8(pMessage).arg(arg1).arg(arg2)); } - - inline void Logger::trace(const char *pMessage, - const QString &rArg1, - const QString &rArg2, - const QString &rArg3) const - { if (isEnabledFor(Level::TRACE_INT)) - forcedLog(Level::TRACE_INT, QString::fromUtf8(pMessage).arg(rArg1, rArg2, rArg3)); } - - inline void Logger::trace(const char *pMessage, - const QString &rArg1, - const QString &rArg2, - int arg3) const - { if (isEnabledFor(Level::TRACE_INT)) - forcedLog(Level::TRACE_INT, QString::fromUtf8(pMessage).arg(rArg1, rArg2).arg(arg3)); } - - inline void Logger::trace(const char *pMessage, - const QString &rArg1, - int arg2, - const QString &rArg3) const - { if (isEnabledFor(Level::TRACE_INT)) - forcedLog(Level::TRACE_INT, QString::fromUtf8(pMessage).arg(rArg1).arg(arg2).arg(rArg3)); } - - inline void Logger::trace(const char *pMessage, - const QString &rArg1, - int arg2, - int arg3) const - { if (isEnabledFor(Level::TRACE_INT)) - forcedLog(Level::TRACE_INT, QString::fromUtf8(pMessage).arg(rArg1).arg(arg2).arg(arg3)); } - - inline void Logger::trace(const char *pMessage, - int arg1, - const QString &rArg2, - const QString &rArg3) const - { if (isEnabledFor(Level::TRACE_INT)) - forcedLog(Level::TRACE_INT, QString::fromUtf8(pMessage).arg(arg1).arg(rArg2).arg(rArg3)); } - - inline void Logger::trace(const char *pMessage, - int arg1, - const QString &rArg2, - int arg3) const - { if (isEnabledFor(Level::TRACE_INT)) - forcedLog(Level::TRACE_INT, QString::fromUtf8(pMessage).arg(arg1).arg(rArg2).arg(arg3)); } - - inline void Logger::trace(const char *pMessage, - int arg1, - int arg2, - const QString &rArg3) const - { if (isEnabledFor(Level::TRACE_INT)) - forcedLog(Level::TRACE_INT, QString::fromUtf8(pMessage).arg(arg1).arg(arg2).arg(rArg3)); } - - inline void Logger::trace(const char *pMessage, - int arg1, - int arg2, - int arg3) const - { if (isEnabledFor(Level::TRACE_INT)) - forcedLog(Level::TRACE_INT, QString::fromUtf8(pMessage).arg(arg1).arg(arg2).arg(arg3)); } - - inline void Logger::trace(const char *pMessage, - const QVariant &rArg1, - const QVariant &rArg2, - const QVariant &rArg3) const - { if (isEnabledFor(Level::TRACE_INT)) - forcedLog(Level::TRACE_INT, QString::fromUtf8(pMessage).arg(rArg1.toString(), rArg2.toString(), rArg3.toString())); } - - // Log operations: warn - - inline void Logger::warn(const QString &rMessage) const - { if (isEnabledFor(Level::WARN_INT)) - forcedLog(Level::WARN_INT, rMessage); } - - inline void Logger::warn(const LogError &rLogError) const - { if (isEnabledFor(Level::WARN_INT)) - forcedLog(Level::WARN_INT, rLogError.toString()); } - - inline void Logger::warn(const char *pMessage) const - { if (isEnabledFor(Level::WARN_INT)) - forcedLog(Level::WARN_INT, QString::fromUtf8(pMessage)); } - - inline void Logger::warn(const char *pMessage, - const QString &rArg1) const - { if (isEnabledFor(Level::WARN_INT)) - forcedLog(Level::WARN_INT, QString::fromUtf8(pMessage).arg(rArg1)); } - - inline void Logger::warn(const char *pMessage, - int arg1) const - { if (isEnabledFor(Level::WARN_INT)) - forcedLog(Level::WARN_INT, QString::fromUtf8(pMessage).arg(arg1)); } - - inline void Logger::warn(const char *pMessage, - const QString &rArg1, - const QString &rArg2) const - { if (isEnabledFor(Level::WARN_INT)) - forcedLog(Level::WARN_INT, QString::fromUtf8(pMessage).arg(rArg1, rArg2)); } - - inline void Logger::warn(const char *pMessage, - const QString &rArg1, - int arg2) const - { if (isEnabledFor(Level::WARN_INT)) - forcedLog(Level::WARN_INT, QString::fromUtf8(pMessage).arg(rArg1).arg(arg2)); } - - inline void Logger::warn(const char *pMessage, - int arg1, - const QString &rArg2) const - { if (isEnabledFor(Level::WARN_INT)) - forcedLog(Level::WARN_INT, QString::fromUtf8(pMessage).arg(arg1).arg(rArg2)); } - - inline void Logger::warn(const char *pMessage, - int arg1, - int arg2) const - { if (isEnabledFor(Level::WARN_INT)) - forcedLog(Level::WARN_INT, QString::fromUtf8(pMessage).arg(arg1).arg(arg2)); } - - inline void Logger::warn(const char *pMessage, - const QString &rArg1, - const QString &rArg2, - const QString &rArg3) const - { if (isEnabledFor(Level::WARN_INT)) - forcedLog(Level::WARN_INT, QString::fromUtf8(pMessage).arg(rArg1, rArg2, rArg3)); } - - inline void Logger::warn(const char *pMessage, - const QString &rArg1, - const QString &rArg2, - int arg3) const - { if (isEnabledFor(Level::WARN_INT)) - forcedLog(Level::WARN_INT, QString::fromUtf8(pMessage).arg(rArg1, rArg2).arg(arg3)); } - - inline void Logger::warn(const char *pMessage, - const QString &rArg1, - int arg2, - const QString &rArg3) const - { if (isEnabledFor(Level::WARN_INT)) - forcedLog(Level::WARN_INT, QString::fromUtf8(pMessage).arg(rArg1).arg(arg2).arg(rArg3)); } - - inline void Logger::warn(const char *pMessage, - const QString &rArg1, - int arg2, - int arg3) const - { if (isEnabledFor(Level::WARN_INT)) - forcedLog(Level::WARN_INT, QString::fromUtf8(pMessage).arg(rArg1).arg(arg2).arg(arg3)); } - - inline void Logger::warn(const char *pMessage, - int arg1, - const QString &rArg2, - const QString &rArg3) const - { if (isEnabledFor(Level::WARN_INT)) - forcedLog(Level::WARN_INT, QString::fromUtf8(pMessage).arg(arg1).arg(rArg2).arg(rArg3)); } - - inline void Logger::warn(const char *pMessage, - int arg1, - const QString &rArg2, - int arg3) const - { if (isEnabledFor(Level::WARN_INT)) - forcedLog(Level::WARN_INT, QString::fromUtf8(pMessage).arg(arg1).arg(rArg2).arg(arg3)); } - - inline void Logger::warn(const char *pMessage, - int arg1, - int arg2, - const QString &rArg3) const - { if (isEnabledFor(Level::WARN_INT)) - forcedLog(Level::WARN_INT, QString::fromUtf8(pMessage).arg(arg1).arg(arg2).arg(rArg3)); } - - inline void Logger::warn(const char *pMessage, - int arg1, - int arg2, - int arg3) const - { if (isEnabledFor(Level::WARN_INT)) - forcedLog(Level::WARN_INT, QString::fromUtf8(pMessage).arg(arg1).arg(arg2).arg(arg3)); } - - inline void Logger::warn(const char *pMessage, - const QVariant &rArg1, - const QVariant &rArg2, - const QVariant &rArg3) const - { if (isEnabledFor(Level::WARN_INT)) - forcedLog(Level::WARN_INT, QString::fromUtf8(pMessage).arg(rArg1.toString(), rArg2.toString(), rArg3.toString())); } - - -} // namespace Log4Qt - - -// Q_DECLARE_TYPEinfo(Log4Qt::Logger, Q_COMPLEX_TYPE); // Use default - - -#endif // LOG4QT_LOGGER_H diff --git a/src/log4qt/src/log4qt/loggerrepository.cpp b/src/log4qt/src/log4qt/loggerrepository.cpp deleted file mode 100644 index b541bb2..0000000 --- a/src/log4qt/src/log4qt/loggerrepository.cpp +++ /dev/null @@ -1,75 +0,0 @@ -/****************************************************************************** - * - * package: Log4Qt - * file: loggerrepository.cpp - * created: September 2007 - * author: Martin Heinrich - * - * - * Copyright 2007 Martin Heinrich - * - * 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. - * - ******************************************************************************/ - - - -/****************************************************************************** - * Dependencies - ******************************************************************************/ - - -#include "log4qt/loggerrepository.h" - -#include - - - -namespace Log4Qt -{ - - - /************************************************************************** - * Declarations - **************************************************************************/ - - - - /************************************************************************** - * C helper functions - **************************************************************************/ - - - - /************************************************************************** - * Class implementation: LoggerRepository - **************************************************************************/ - - - - /************************************************************************** - * Implementation: Operators, Helper - **************************************************************************/ - - -#ifndef QT_NO_DEBUG_STREAM - QDebug operator<<(QDebug debug, - const LoggerRepository &rLoggerRepository) - { - return rLoggerRepository.debug(debug); - } -#endif // QT_NO_DEBUG_STREAM - - - -} // namespace Log4Qt diff --git a/src/log4qt/src/log4qt/loggerrepository.h b/src/log4qt/src/log4qt/loggerrepository.h deleted file mode 100644 index 13c0488..0000000 --- a/src/log4qt/src/log4qt/loggerrepository.h +++ /dev/null @@ -1,128 +0,0 @@ -/****************************************************************************** - * - * package: Log4Qt - * file: loggerrepository.h - * created: September 2007 - * author: Martin Heinrich - * - * - * Copyright 2007 Martin Heinrich - * - * 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. - * - ******************************************************************************/ - -#ifndef LOG4QT_LOGGERREPOSITORY_H -#define LOG4QT_LOGGERREPOSITORY_H - - -/****************************************************************************** - * Dependencies - ******************************************************************************/ - -#include -#include "log4qt/level.h" - - -/****************************************************************************** - * Declarations - ******************************************************************************/ - -namespace Log4Qt -{ - - class Logger; - - /*! - * \brief The class LoggerRepository is abstract base class for a logger - * repository. - */ - class LoggerRepository - { - public: - // LoggerRepository(); // Use compiler default - // LoggerRepository(const LoggerRepository &rOther); // Use compiler default - // virtual ~LoggerRepository(); // Use compiler default - // LoggerRepository &operator=(const LoggerRepository &rOther); // Use compiler default - - public: - virtual bool exists(const QString &rName) const = 0; - virtual Logger *logger(const QString &rName) = 0; - // JAVA: virtual Logger *logger(const String &rName, LoggerFactory *pFactory); - virtual QList loggers() const = 0; - virtual Logger *rootLogger() const = 0; - virtual Level threshold() const = 0; - virtual void setThreshold(Level level) = 0; - virtual void setThreshold(const QString &rThreshold) = 0; - - virtual bool isDisabled(Level level) = 0; - virtual void resetConfiguration() = 0; - virtual void shutdown() = 0; - - // JAVA: virtual void addHierarchyEventListener(HierarchyEventListener *pEventListener); - // JAVA: virtual void emitNoAppenderWarning(Logger *plogger) const; - // JAVA: virtual void fireAddAppenderEvent(Logger *plogger, Appender *pAppender) const; - - protected: -#ifndef QT_NO_DEBUG_STREAM - /*! - *\relates LoggerRepository - * - * Writes all object member variables to the given debug stream \a rDebug - * and returns the stream. - * - * The member function is used by - * QDebug operator<<(QDebug debug, const LoggerRepository &rLoggerRepository) - * to generate class specific output. - * - * \sa QDebug operator<<(QDebug debug, const LoggerRepository &rLoggerRepository) - */ - virtual QDebug debug(QDebug &rDebug) const = 0; - friend QDebug operator<<(QDebug debug, - const LoggerRepository &rLoggerRepository); -#endif - }; - - - /****************************************************************************** - * Operators, Helper - ******************************************************************************/ - -#ifndef QT_NO_DEBUG_STREAM - /*! - * \relates LoggerRepository - * Writes all object member variables to the given debug stream \a debug - * and returns the stream. - * - * To handle subclassing the function uses the virtual member function - * debug(). This allows each class to generate its own output. - * - * \sa QDebug, debug() - */ - QDebug operator<<(QDebug debug, - const LoggerRepository &rLoggerRepository); -#endif - - - /************************************************************************** - * Inline - **************************************************************************/ - - -} // namespace Log4Qt - - -// Q_DECLARE_TYPEINFO(Log4Qt::LoggerRepository, Q_COMPLEX_TYPE); // Use default - - -#endif // LOG4QT_LOGGERREPOSITORY_H diff --git a/src/log4qt/src/log4qt/loggingevent.cpp b/src/log4qt/src/log4qt/loggingevent.cpp deleted file mode 100644 index 161f01c..0000000 --- a/src/log4qt/src/log4qt/loggingevent.cpp +++ /dev/null @@ -1,272 +0,0 @@ -/****************************************************************************** - * - * package: Log4Qt - * file: loggingevent.cpp - * created: September 2007 - * author: Martin Heinrich - * - * - * Copyright 2007 Martin Heinrich - * - * 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. - * - *****************************************************************************/ - - - -/****************************************************************************** - * Dependencies - ******************************************************************************/ - - -#include "log4qt/loggingevent.h" - -#include -#include -#include -#include -#include -#include -#include "log4qt/helpers/datetime.h" -#include "log4qt/helpers/initialisationhelper.h" -#include "log4qt/logger.h" -#include "log4qt/mdc.h" -#include "log4qt/ndc.h" - - - -namespace Log4Qt -{ - - - /************************************************************************** - * Declarations - **************************************************************************/ - - - LOG4QT_GLOBAL_STATIC(QMutex, sequence_guard) - - - - /************************************************************************** - * C helper functions - **************************************************************************/ - - - - /************************************************************************** - * Class implementation: LoggingEvent - **************************************************************************/ - - - LoggingEvent::LoggingEvent() : - mLevel(Level::NULL_INT), - mpLogger(0), - mMessage(), - mNdc(NDC::peek()), - mProperties(MDC::context()), - mSequenceNumber(nextSequenceNumber()), - mThreadName(), - mTimeStamp(DateTime::currentDateTime().toMilliSeconds()) - { - setThreadNameToCurrent(); - } - - - LoggingEvent::LoggingEvent(const Logger *pLogger, - Level level, - const QString &rMessage) : - mLevel(level), - mpLogger(pLogger), - mMessage(rMessage), - mNdc(NDC::peek()), - mProperties(MDC::context()), - mSequenceNumber(nextSequenceNumber()), - mThreadName(), - mTimeStamp(DateTime::currentDateTime().toMilliSeconds()) - { - setThreadNameToCurrent(); - } - - - LoggingEvent::LoggingEvent(const Logger *pLogger, - Level level, - const QString &rMessage, - qint64 timeStamp) : - mLevel(level), - mpLogger(pLogger), - mMessage(rMessage), - mNdc(NDC::peek()), - mProperties(MDC::context()), - mSequenceNumber(nextSequenceNumber()), - mThreadName(), - mTimeStamp(timeStamp) - { - setThreadNameToCurrent(); - } - - - LoggingEvent::LoggingEvent(const Logger *pLogger, - Level level, - const QString &rMessage, - const QString &rNdc, - const QHash &rProperties, - const QString &rThreadName, - qint64 timeStamp) : - mLevel(level), - mpLogger(pLogger), - mMessage(rMessage), - mNdc(rNdc), - mProperties(rProperties), - mSequenceNumber(nextSequenceNumber()), - mThreadName(rThreadName), - mTimeStamp(timeStamp) - { - } - - - QString LoggingEvent::loggerName() const - { - if (mpLogger) - return mpLogger->name(); - else - return QString(); - } - - - QString LoggingEvent::toString() const - { - return level().toString() + QLatin1Char(':') + message(); - } - - - qint64 LoggingEvent::sequenceCount() - { - QMutexLocker locker(sequence_guard()); - - return msSequenceCount; - } - - - qint64 LoggingEvent::startTime() - { - return InitialisationHelper::startTime(); - } - - - void LoggingEvent::setThreadNameToCurrent() - { - if (QThread::currentThread()) - mThreadName = QThread::currentThread()->objectName(); - } - - - qint64 LoggingEvent::nextSequenceNumber() - { - QMutexLocker locker(sequence_guard()); - - return ++msSequenceCount; - } - - - qint64 LoggingEvent::msSequenceCount = 0; - - - - /************************************************************************** - * Implementation: Operators, Helper - **************************************************************************/ - - -#ifndef QT_NO_DATASTREAM - QDataStream &operator<<(QDataStream &rStream, const LoggingEvent &rLoggingEvent) - { - QBuffer buffer; - buffer.open(QIODevice::WriteOnly); - QDataStream stream(&buffer); - - // version - quint16 version = 0; - stream << version; - // version 0 data - stream << rLoggingEvent.mLevel - << rLoggingEvent.loggerName() - << rLoggingEvent.mMessage - << rLoggingEvent.mNdc - << rLoggingEvent.mProperties - << rLoggingEvent.mSequenceNumber - << rLoggingEvent.mThreadName - << rLoggingEvent.mTimeStamp; - - buffer.close(); - rStream << buffer.buffer(); - return rStream; - } - - - QDataStream &operator>>(QDataStream &rStream, LoggingEvent &rLoggingEvent) - { - QByteArray array; - rStream >> array; - QBuffer buffer(&array); - buffer.open(QIODevice::ReadOnly); - QDataStream stream(&buffer); - - // version - quint16 version; - stream >> version; - // Version 0 data - QString logger; - stream >> rLoggingEvent.mLevel - >> logger - >> rLoggingEvent.mMessage - >> rLoggingEvent.mNdc - >> rLoggingEvent.mProperties - >> rLoggingEvent.mSequenceNumber - >> rLoggingEvent.mThreadName - >> rLoggingEvent.mTimeStamp; - if (logger.isEmpty()) - rLoggingEvent.mpLogger = 0; - else - rLoggingEvent.mpLogger = Logger::logger(logger); - - buffer.close(); - return rStream; - } -#endif // QT_NO_DATASTREAM - - -#ifndef QT_NO_DEBUG_STREAM - QDebug operator<<(QDebug debug, - const LoggingEvent &rLoggingEvent) - { - QString logger; - if (rLoggingEvent.logger() != 0) - logger = rLoggingEvent.logger()->name(); - - debug.nospace() << "LoggingEvent(" - << "level:" << rLoggingEvent.level().toString() << " " - << "logger:" << logger << " " - << "message:" << rLoggingEvent.message() << " " - << "sequencenumber:" << rLoggingEvent.sequenceNumber() << " " - << "threadname:" << rLoggingEvent.threadName() << " " - << "timestamp:" << rLoggingEvent.timeStamp() - << "(" << DateTime::fromMilliSeconds(rLoggingEvent.timeStamp()) << ")" - << "sequenceCount:" << rLoggingEvent.sequenceCount() - << ")"; - return debug.space(); - } -#endif // QT_NO_DEBUG_STREAM - - -} // namespace Log4Qt diff --git a/src/log4qt/src/log4qt/loggingevent.h b/src/log4qt/src/log4qt/loggingevent.h deleted file mode 100644 index 87e2ed6..0000000 --- a/src/log4qt/src/log4qt/loggingevent.h +++ /dev/null @@ -1,221 +0,0 @@ -/****************************************************************************** -* -* package: Log4Qt -* file: loggingevent.h -* created: September 2007 -* author: Martin Heinrich - * - * - * Copyright 2007 Martin Heinrich - * - * 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. - * -******************************************************************************/ - -#ifndef LOG4QT_LOG4QTEVENT_H -#define LOG4QT_LOG4QTEVENT_H - - -/****************************************************************************** - * Dependencies - ******************************************************************************/ - -#include -#include -#include -#include -#include "log4qt/level.h" - - -/****************************************************************************** - * Declarations - ******************************************************************************/ - -namespace Log4Qt -{ - - class Logger; - - /*! - * \brief The class LoggingEvent is the internal representation of a - * logging event. - * - * The class uses milliseconds since 1970-01-01T00:00:00, Coordinated - * Universal Time for time values. For converstion from and to QDateTime - * use DateTime. - */ - class LoggingEvent - { - public: - LoggingEvent(); - LoggingEvent(const Logger *pLogger, - Level level, - const QString &rMessage); - LoggingEvent(const Logger *pLogger, - Level level, - const QString &rMessage, - qint64 timeStamp); - LoggingEvent(const Logger *pLogger, - Level level, - const QString &rMessage, - const QString &rNdc, - const QHash &rProperties, - const QString &rThreadName, - qint64 timeStamp); - // LoggingEvent(const LoggingEvent &LoggingEvent::rOther); // Use compiler default - // virtual ~LoggingEvent(); // Use compiler default - // LoggingEvent &operator=(const LoggingEvent &LoggingEvent::rOther); // Use compiler default - - // JAVA: QString fqnOfLoggerClass() const; - Level level() const; - // LocationInformation locationInformation() const; - const Logger *logger() const; - QString message() const; - QHash mdc() const; - QString ndc() const; - QHash properties() const; - qint64 sequenceNumber() const; - QString threadName() const; - // JAVA: ThrowableInformation throwableInformation() const; - qint64 timeStamp() const; - - // JAVA: bool locationInformationExists() const; - QString loggerName() const; - QString property(const QString &rKey) const; - QStringList propertyKeys() const; - void setProperty(const QString &rKey, const QString &rValue); - // JAVA: QString throwableStrRep() const; - QString toString() const; - static qint64 sequenceCount(); - static qint64 startTime(); - - private: - void setThreadNameToCurrent(); - static qint64 nextSequenceNumber(); - - private: - Level mLevel; - const Logger *mpLogger; - QString mMessage; - QString mNdc; - QHash mProperties; - qint64 mSequenceNumber; - QString mThreadName; - qint64 mTimeStamp; - static qint64 msSequenceCount; - -#ifndef QT_NO_DATASTREAM - // Needs to be friend to stream objects - friend QDataStream &operator<<(QDataStream &rStream, - const LoggingEvent &rLoggingEvent); - friend QDataStream &operator>>(QDataStream &rStream, - LoggingEvent &rLoggingEvent); -#endif // QT_NO_DATASTREAM - }; - - - /************************************************************************** - * Operators, Helper - **************************************************************************/ - -#ifndef QT_NO_DATASTREAM - /*! - * \relates LoggingEvent - * - * Writes the given error \a rLoggingEvent to the given stream \a rStream, - * and returns a reference to the stream. - */ - QDataStream &operator<<(QDataStream &rStream, - const LoggingEvent &rLoggingEvent); - - /*! - * \relates LoggingEvent - * - * Reads an error from the given stream \a rStream into the given - * error \a rLoggingEvent, and returns a reference to the stream. - */ - QDataStream &operator>>(QDataStream &rStream, - LoggingEvent &rLoggingEvent); -#endif // QT_NO_DATASTREAM - -#ifndef QT_NO_DEBUG_STREAM - /*! - * \relates LoggingEvent - * - * Writes all object member variables to the given debug stream \a debug and - * returns the stream. - * - * - * %LoggingEvent(level:"WARN" logger:"Log4Qt::Properties" - * message:"Unknown escape sequence '\j' in property starting at line 1" - * sequencenumber:14 threadname:"main" - * timestamp:1194337148937(QDateTime("Tue Nov 6 03:19:08 2007") ) - * sequenceCount: 14 ) - * - * - * \sa QDebug - */ - QDebug operator<<(QDebug debug, - const LoggingEvent &rLoggingEvent); -#endif // QT_NO_DEBUG_STREAM - - - /************************************************************************** - * Inline - **************************************************************************/ - - inline Level LoggingEvent::level() const - { return mLevel; } - - inline const Logger *LoggingEvent::logger() const - { return mpLogger; } - - inline QString LoggingEvent::message() const - { return mMessage; } - - inline QHash LoggingEvent::mdc() const - { return mProperties; } - - inline QString LoggingEvent::ndc() const - { return mNdc; } - - inline QHash LoggingEvent::properties() const - { return mProperties; } - - inline qint64 LoggingEvent::sequenceNumber() const - { return mSequenceNumber; } - - inline QString LoggingEvent::threadName() const - { return mThreadName; } - - inline qint64 LoggingEvent::timeStamp() const - { return mTimeStamp; } - - inline QString LoggingEvent::property(const QString &rKey) const - { return mProperties.value(rKey); } - - inline QStringList LoggingEvent::propertyKeys() const - { return QStringList(mProperties.keys()); } - - inline void LoggingEvent::setProperty(const QString &rKey, const QString &rValue) - { mProperties.insert(rKey, rValue); } - - -} // namespace Log4Qt - - -Q_DECLARE_METATYPE(Log4Qt::LoggingEvent) -Q_DECLARE_TYPEINFO(Log4Qt::LoggingEvent, Q_MOVABLE_TYPE); - - -#endif // LOG4QT_LOG4QTEVENT_H diff --git a/src/log4qt/src/log4qt/logmanager.cpp b/src/log4qt/src/log4qt/logmanager.cpp deleted file mode 100644 index 47f2e2b..0000000 --- a/src/log4qt/src/log4qt/logmanager.cpp +++ /dev/null @@ -1,504 +0,0 @@ -/****************************************************************************** - * - * package: Log4Qt - * file: logmanager.cpp - * created: September 2007 - * author: Martin Heinrich - * - * - * changes: Sep 2008, Martin Heinrich: - * - Resolved compilation problem with Microsoft Visual Studio 2005 - * Feb 2009, Martin Heinrich - * - Fixed VS 2008 unreferenced formal parameter warning by using - * Q_UNUSED in operator<<. - * - * - * Copyright 2007 - 2009 Martin Heinrich - * - * 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. - * - ******************************************************************************/ - - - -/****************************************************************************** - * Dependencies - ******************************************************************************/ - - -#include "log4qt/logmanager.h" - -#include -#include -#include -#include -#include -#include -#include "log4qt/consoleappender.h" -#include "log4qt/helpers/datetime.h" -#include "log4qt/helpers/initialisationhelper.h" -#include "log4qt/helpers/optionconverter.h" -#include "log4qt/hierarchy.h" -#include "log4qt/propertyconfigurator.h" -#include "log4qt/ttcclayout.h" -#include "log4qt/varia/denyallfilter.h" -#include "log4qt/varia/levelrangefilter.h" - - -namespace Log4Qt -{ - - - /************************************************************************** - * Declarations - **************************************************************************/ - - - - /************************************************************************** - * C helper functions - **************************************************************************/ - - - LOG4QT_DECLARE_STATIC_LOGGER(static_logger, Log4Qt::LogManager) - LOG4QT_GLOBAL_STATIC(QMutex, singleton_guard) - - - - /************************************************************************** - * Class implementation: LogManager - **************************************************************************/ - - - LogManager::LogManager() : - mObjectGuard(QMutex::Recursive), // Recursive for doStartup() to call doConfigureLogLogger() - mpLoggerRepository(new Hierarchy()), - mHandleQtMessages(false), - mOldQtMsgHandler(0) - { - } - - - LogManager::~LogManager() - { - static_logger()->warn("Unexpected destruction of LogManager"); - - // doSetConfigureHandleQtMessages(false); - // delete mpLoggerRepository; - } - - - Logger *LogManager::rootLogger() - { - return instance()->mpLoggerRepository->rootLogger(); - } - - - QList LogManager::loggers() - { - return instance()->mpLoggerRepository->loggers(); - } - - - Level LogManager::threshold() - { - return instance()->mpLoggerRepository->threshold(); - } - - - void LogManager::setThreshold(Level level) - { - instance()->mpLoggerRepository->setThreshold(level); - } - - - bool LogManager::exists(const char *pName) - { - return instance()->mpLoggerRepository->exists(QLatin1String(pName)); - } - - - LogManager *LogManager::instance() - { - // Do not use LOG4QT_GLOBAL_STATIC. The LogManager is rather expensive - // to construct, an exit handler must be set and doStartup must be - // called. - - if (!mspInstance) - { - QMutexLocker locker(singleton_guard()); - if (!mspInstance) - { - mspInstance = new LogManager; - // qAddPostRoutine(shutdown); - atexit(shutdown); - mspInstance->doConfigureLogLogger(); - mspInstance->welcome(); - mspInstance->doStartup(); - } - } - return mspInstance; - } - - - Logger *LogManager::logger(const QString &rName) - { - return instance()->mpLoggerRepository->logger(rName); - } - - - void LogManager::resetConfiguration() - { - setHandleQtMessages(false); - instance()->mpLoggerRepository->resetConfiguration(); - configureLogLogger(); - } - - - const char* LogManager::version() - { - return LOG4QT_VERSION_STR; - } - - - void LogManager::shutdown() - { - instance()->mpLoggerRepository->shutdown(); - } - - - void LogManager::doSetHandleQtMessages(bool handleQtMessages) - { - QMutexLocker locker(&mObjectGuard); - - if (instance()->mHandleQtMessages == handleQtMessages) - return; - - instance()->mHandleQtMessages = handleQtMessages; - if (instance()->mHandleQtMessages) - { - static_logger()->trace("Activate Qt message handling"); -#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0) - instance()->mOldQtMsgHandler = qInstallMsgHandler(qtMessageHandler); -#else - instance()->mOldQtMsgHandler = qInstallMessageHandler(qtMessageHandler); -#endif - } - else - { - static_logger()->trace("Deactivate Qt message handling"); -#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0) - qInstallMsgHandler(instance()->mOldQtMsgHandler); -#else - qInstallMessageHandler(instance()->mOldQtMsgHandler); -#endif - } - } - - - void LogManager::doConfigureLogLogger() - { - QMutexLocker locker(&instance()->mObjectGuard); - - // Level - QString value = InitialisationHelper::setting(QLatin1String("Debug"), - QLatin1String("ERROR")); - logLogger()->setLevel(OptionConverter::toLevel(value, Level::DEBUG_INT)); - - // Common layout - TTCCLayout *p_layout = new TTCCLayout(); - p_layout->setName(QLatin1String("LogLog TTCC")); - p_layout->setContextPrinting(false); - p_layout->activateOptions(); - - // Common deny all filter - Filter *p_denyall = new DenyAllFilter(); - p_denyall->activateOptions(); - - // ConsoleAppender on stdout for all events <= INFO - ConsoleAppender *p_appender; - LevelRangeFilter *p_filter; - p_appender = new ConsoleAppender(p_layout, ConsoleAppender::STDOUT_TARGET); - p_filter = new LevelRangeFilter(); - p_filter->setNext(p_denyall); - p_filter->setLevelMin(Level::NULL_INT); - p_filter->setLevelMax(Level::INFO_INT); - p_filter->activateOptions(); - p_appender->setName(QLatin1String("LogLog stdout")); - p_appender->addFilter(p_filter); - p_appender->activateOptions(); - logLogger()->addAppender(p_appender); - - // ConsoleAppender on stderr for all events >= WARN - p_appender = new ConsoleAppender(p_layout, ConsoleAppender::STDERR_TARGET); - p_filter = new LevelRangeFilter(); - p_filter->setNext(p_denyall); - p_filter->setLevelMin(Level::WARN_INT); - p_filter->setLevelMax(Level::OFF_INT); - p_filter->activateOptions(); - p_appender->setName(QLatin1String("LogLog stderr")); - p_appender->addFilter(p_filter); - p_appender->activateOptions(); - logLogger()->addAppender(p_appender); - } - - - void LogManager::doStartup() - { - QMutexLocker locker(&instance()->mObjectGuard); - - // Override - QString default_value = QLatin1String("false"); - QString value = InitialisationHelper::setting(QLatin1String("DefaultInitOverride"), - default_value); - if (value != default_value) - { - static_logger()->debug("DefaultInitOverride is set. Aborting default initialisation"); - return; - } - - // Configuration using setting Configuration - value = InitialisationHelper::setting(QLatin1String("Configuration")); - if (QFile::exists(value)) - { - static_logger()->debug("Default initialisation configures from file '%1' specified by Configure", value); - PropertyConfigurator::configure(value); - return; - } - - // Configuration using setting - if (QCoreApplication::instance()) - { - const QLatin1String log4qt_group("Log4Qt"); - const QLatin1String properties_group("Properties"); - QSettings s; - s.beginGroup(log4qt_group); - if (s.childGroups().contains(properties_group)) - { - const QString group(QLatin1String("Log4Qt/Properties")); - static_logger()->debug("Default initialisation configures from setting '%1/%2'", log4qt_group, properties_group); - s.beginGroup(properties_group); - PropertyConfigurator::configure(s); - return; - } - } - - // Configuration using default file - const QString default_file(QLatin1String("log4qt.properties")); - if (QFile::exists(default_file)) - { - static_logger()->debug("Default initialisation configures from default file '%1'", default_file); - PropertyConfigurator::configure(default_file); - return; - } - - static_logger()->debug("Default initialisation leaves package unconfigured"); - } - - - void LogManager::welcome() - { - static_logger()->info("Initialising Log4Qt %1", - QLatin1String(LOG4QT_VERSION_STR)); - - // Debug: Info - if (static_logger()->isDebugEnabled()) - { - // Create a nice timestamp with UTC offset - DateTime start_time = DateTime::fromMilliSeconds(InitialisationHelper::startTime()); - QString offset; - { - QDateTime utc = start_time.toUTC(); - QDateTime local = start_time.toLocalTime(); - QDateTime local_as_utc = QDateTime(local.date(), local.time(), Qt::UTC); - int min = utc.secsTo(local_as_utc) / 60; - if (min < 0) - offset += QLatin1Char('-'); - else - offset += QLatin1Char('+'); - min = abs(min); - offset += QString::number(min / 60).rightJustified(2, QLatin1Char('0')); - offset += QLatin1Char(':'); - offset += QString::number(min % 60).rightJustified(2, QLatin1Char('0')); - } - static_logger()->debug("Program startup time is %1 (UTC%2)", - start_time.toString(QLatin1String("ISO8601")), - offset); - static_logger()->debug("Internal logging uses the level %1", - logLogger()->level().toString()); - } - - // Trace: Dump settings - if (static_logger()->isTraceEnabled()) - { - static_logger()->trace("Settings from the system environment:"); - QString entry; - Q_FOREACH (entry, InitialisationHelper::environmentSettings().keys()) - static_logger()->trace(" %1: '%2'", - entry, - InitialisationHelper::environmentSettings().value(entry)); - - static_logger()->trace("Settings from the application settings:"); - if (QCoreApplication::instance()) - { - const QLatin1String log4qt_group("Log4Qt"); - const QLatin1String properties_group("Properties"); - static_logger()->trace(" %1:", log4qt_group); - QSettings s; - s.beginGroup(log4qt_group); - Q_FOREACH (entry, s.childKeys()) - static_logger()->trace(" %1: '%2'", - entry, - s.value(entry).toString()); - static_logger()->trace(" %1/%2:", log4qt_group, properties_group); - s.beginGroup(properties_group); - Q_FOREACH (entry, s.childKeys()) - static_logger()->trace(" %1: '%2'", - entry, - s.value(entry).toString()); - } else - static_logger()->trace(" QCoreApplication::instance() is not available"); - } - } - -#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0) - void LogManager::qtMessageHandler(QtMsgType type, const char *pMessage) - { - Level level; - switch (type) - { - case QtDebugMsg: - level = Level::DEBUG_INT; - break; - case QtWarningMsg: - level = Level::WARN_INT; - break; - case QtCriticalMsg: - level = Level::ERROR_INT; - break; - case QtFatalMsg: - level = Level::FATAL_INT; - break; - default: - level = Level::TRACE_INT; - } - instance()->qtLogger()->log(level, pMessage); - - // Qt fatal behaviour copied from global.cpp qt_message_output() - // begin { - - if ((type == QtFatalMsg) || - ((type == QtWarningMsg) && (!qgetenv("QT_FATAL_WARNINGS").isNull())) ) - { -#if defined(Q_CC_MSVC) && defined(QT_DEBUG) && defined(_DEBUG) && defined(_CRT_ERROR) - // get the current report mode - int reportMode = _CrtSetReportMode(_CRT_ERROR, _CRTDBG_MODE_WNDW); - _CrtSetReportMode(_CRT_ERROR, reportMode); - int ret = _CrtDbgReport(_CRT_ERROR, __FILE__, __LINE__, QT_VERSION_STR, pMessage); - if (ret == 0 && reportMode & _CRTDBG_MODE_WNDW) - return; // ignore - else if (ret == 1) - _CrtDbgBreak(); -#endif - -#if defined(Q_OS_UNIX) && defined(QT_DEBUG) - abort(); // trap; generates core dump -#else - exit(1); // goodbye cruel world -#endif - } - - // } end - } -#else - void LogManager::qtMessageHandler(QtMsgType type, const QMessageLogContext &context, const QString &message) - { - Level level; - switch (type) - { - case QtDebugMsg: - level = Level::DEBUG_INT; - break; - case QtWarningMsg: - level = Level::WARN_INT; - break; - case QtCriticalMsg: - level = Level::ERROR_INT; - break; - case QtFatalMsg: - level = Level::FATAL_INT; - break; - default: - level = Level::TRACE_INT; - } - QString newMsg = QString("%1:%2(%3)-").arg(context.file).arg(context.function).arg(context.line); - instance()->qtLogger()->log(level, newMsg+message); - - // Qt fatal behaviour copied from global.cpp qt_message_output() - // begin { - - if ((type == QtFatalMsg) || - ((type == QtWarningMsg) && (!qgetenv("QT_FATAL_WARNINGS").isNull())) ) - { -#if defined(Q_CC_MSVC) && defined(QT_DEBUG) && defined(_DEBUG) && defined(_CRT_ERROR) - // get the current report mode - int reportMode = _CrtSetReportMode(_CRT_ERROR, _CRTDBG_MODE_WNDW); - _CrtSetReportMode(_CRT_ERROR, reportMode); - int ret = _CrtDbgReport(_CRT_ERROR, __FILE__, __LINE__, QT_VERSION_STR, message.toUtf8().constData()); - if (ret == 0 && reportMode & _CRTDBG_MODE_WNDW) - return; // ignore - else if (ret == 1) - _CrtDbgBreak(); -#endif - -#if defined(Q_OS_UNIX) && defined(QT_DEBUG) - abort(); // trap; generates core dump -#else - exit(1); // goodbye cruel world -#endif - } - - // } end - } -#endif - - - - LogManager *LogManager::mspInstance = 0; - - - - /************************************************************************** - * Implementation: Operators, Helper - **************************************************************************/ - - -#ifndef QT_NO_DEBUG_STREAM - QDebug operator<<(QDebug debug, const LogManager &rLogManager) - { - Q_UNUSED(rLogManager); // To avoid warning C4100 on VS 2008 - QList loggers = rLogManager.loggers(); - debug.nospace() << "LogManager(" - << "loggerrepository:" << *rLogManager.loggerRepository() - << "log-level:" << rLogManager.logLogger()->level().toString() - << "log-appenders:" << rLogManager.logLogger()->appenders().count() - << "qt-level:" << rLogManager.qtLogger()->level().toString() - << "qt-appenders:" << rLogManager.qtLogger()->appenders().count() - << "handleqtmessages:" << rLogManager.handleQtMessages() - << ")"; - return debug.space(); - } -#endif // QT_NO_DEBUG_STREAM - - -} // namespace Log4Qt diff --git a/src/log4qt/src/log4qt/logmanager.h b/src/log4qt/src/log4qt/logmanager.h deleted file mode 100644 index 27111a0..0000000 --- a/src/log4qt/src/log4qt/logmanager.h +++ /dev/null @@ -1,340 +0,0 @@ -/****************************************************************************** - * - * package: Log4Qt - * file: logmanager.h - * created: September 2007 - * author: Martin Heinrich - * - * - * Copyright 2007 Martin Heinrich - * - * 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. - * - ******************************************************************************/ - -#ifndef LOG4QT_LOGMANAGER_H -#define LOG4QT_LOGMANAGER_H - - -/****************************************************************************** - * Dependencies - ******************************************************************************/ - -#include - -#include -#include -#include -#include -#include "log4qt/level.h" -#include "log4qt/logger.h" - - -/****************************************************************************** - * Declarations - ******************************************************************************/ - -namespace Log4Qt -{ - - class LoggerRepository; - - /*! - * \brief The class LogManager manages Logger in the default - * LoggerRepository. - * - * The LogManager manages logger in a single Hierarchy instance. It - * provides access to special logger over the logLogger(), qtLogger() - * and rootLogger() member functions. - * - * The LogManager is handling the initialisation on startup. The - * initialisation procedure will first attempt to configure the package - * based on environment variables. If the attempt fails it will check for - * the existence of configuration files in several location. For detailed - * description of the initialisation procedure see \ref Init - * "Initialization procedure". - * - * Messages created by qDebug(), qWarning(), qCritical() and qFatal() can - * be can be handled by the LogManager. By default the message handling - * is disabled. It can be enabled by calling setHandleQtMessages(). Once - * enabled all messages are logged using the logger qtLogger(). - * - * The Log4Qt runtime version is accessible over version(). The macros - * \ref Log4Qt::LOG4QT_VERSION "LOG4QT_VERSION" and - * \ref Log4Qt::LOG4QT_VERSION_STR "LOG4QT_VERSION_STR" provide the - * compile time version. - * - * \note All the functions declared in this class are thread-safe. - */ - class LogManager - { - private: - LogManager(); - LogManager(const LogManager &rOther); // Not implemented - virtual ~LogManager(); - LogManager &operator=(const LogManager &rOther); // Not implemented - - public: - /*! - * Returns if the handling of messages created by calls to qDebug(), - * qWarning(), qCritical() and qFatal() is activated. - * - * \sa setHandleQtMessages() - */ - static bool handleQtMessages(); - - static LoggerRepository *loggerRepository(); - - /*! - * Returns the logger used for logging internal messages. See - * \ref LogLog "Logging within the package" for more details. - * - * Calling this function is equivalent to calling logger("Log4Qt"). - */ - static Logger *logLogger(); - - /*! - * Returns a pointer to the logger used for logging messages created by - * calls to qDebug(), qWarning(), qCritical() and qFatal(). - * - * Calling this function is equivalent to calling logger("Qt"). - * - * \sa setHandleQtMessages() - */ - static Logger *qtLogger(); - - static Logger *rootLogger(); - static QList loggers(); - static Level threshold(); - static void setThreshold(Level level); - - /*! - * Activates or deactivates the handling of messages created by calls - * to qDebug(), qWarning(), qCritical() and qFatal() is activated. - * - * If activated, a Qt message handler is installed. Messages are logged - * using the logger returned by qtLogger(). For fatal messages the same - * exit procedure is implemented as for qFatal(). - * - * The following mappping is used from QtMsgType to Level: - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - *
    QtMsgType     %Level
QtDebugMsg Level::DEBUG_INT
QtWarningMsg Level::WARN_INT
QtCriticalMsg Level::ERROR_INT
QtFatalMsg Level::FATAL_INT
QtSystemMsg Level::TRACE_INT
- * - * The default value is false for not handling Qt messages. - * - * \sa handleQtMessages(), qInstallMsgHandler(), qFatal() - */ - static void setHandleQtMessages(bool handleQtMessages); - - /*! - * Configures the logging for the package to its default behaviour. - * - * The logger logLogger() is configured to be not additive. Messages - * with the level Level::ERROR_INT and Level::FATAL_INT are written - * to \c stderr using a ConsoleAppender. The remaining messages are - * written to \c stdout using a second ConsoleAppender. The level is - * read from the system environment or application settings using - * InitialisationHelper::setting() with the key \c Debug. If a level - * value is found, but it is not a valid Level string, - * Level::DEBUG_INT is used. If no level string is found - * Level::ERROR_INT is used. - * - * The function does not remove any appender from the logger - * logLogger(). - * - * \sa \ref LogLog "Logging within the package", - * \ref Env "Environment Variables", - * resetConfiguration(), InitialisationHelper::setting() - */ - static void configureLogLogger(); - - static bool exists(const char *pName); - // JAVA: void fireAddAppenderEvent(Logger *pLogger, Appender *pAppender); - - /*! - * Returns the LogManager instance. - */ - static LogManager *instance(); - - static Logger *logger(const QString &rName); - - /*! - * Reset all values contained in logger repository to their default. - * - * All appenders are removed from all loggers. The loggers are handled - * in no particular order. The last loggers to be reset are qtLogger(), - * logLogger() and rootLogger() in that order. - * - * The handling of messages created by calls to qDebug(), qWarning(), - * qCritical() and qFatal() is deactivated. - * - * The internal logging is initialised to its default bahaviour - * using configureLogLogger(). - * - * \sa LoggerRepository::resetConfiguration(), setHandleQtMessages(), - * configureLogLogger() - */ - static void resetConfiguration(); - - static void shutdown(); - - /*! - * Executes the default initialisation procedure of the package. - * - * The function will test for the setting \c DefaultInitOverride in - * the system environment and application settings using - * \ref InitialisationHelper::setting(). If the value is present and - * set to anything else then \c false, the initialisation is aborted. - *
- * The system environment and application settings are tested for the - * setting \c Configuration. If it is found and it is a valid path to - * a file, the package is configured with the file using - * \ref PropertyConfigurator::doConfigure(const QString &, LoggerRepository *) - * "PropertyConfigurator::doConfigure()". If the setting - * \c Configuration is not available and a QCoreApplication object is - * present, the application settings are tested for a group - * \c Log4Qt/Properties. If the group exists, the package is configured - * with the setting using the - * \ref PropertyConfigurator::doConfigure(const QSettings &r, LoggerRepository *) - * "PropertyConfiguratordoConfigure()". If neither a configuration - * file nor configuration settings could be found, the current working - * directory is searched for the file \c "log4qt.properties". If it is - * found, the package is configured with the file using - * \ref PropertyConfigurator::doConfigure(const QString &, LoggerRepository *) - * "PropertyConfigurator::doConfigure()". - * - * \sa \ref Init "Initialization procedure", - * \ref Env "Environment Variables", - * InitialisationHelper::setting() - */ - static void startup(); - - /*! - * Returns the version number of Log4Qt at run-time. This may be a - * different version than the version the application was compiled - * against. - * - * \sa \ref Log4Qt::LOG4QT_VERSION "LOG4QT_VERSION", - * \ref Log4Qt::LOG4QT_VERSION_STR "LOG4QT_VERSION_STR" - - */ - static const char* version(); - - private: - void doSetHandleQtMessages(bool handleQtMessages); - void doConfigureLogLogger(); - void doStartup(); - void welcome(); -#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0) - static void qtMessageHandler(QtMsgType type, - const char *pMessage); -#else - static void qtMessageHandler(QtMsgType type, - const QMessageLogContext &context, - const QString &message); -#endif - - - private: - mutable QMutex mObjectGuard; - LoggerRepository *mpLoggerRepository; - Logger *mpNullLogger; - bool mHandleQtMessages; -#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0) - QtMsgHandler mOldQtMsgHandler; -#else - QtMessageHandler mOldQtMsgHandler; -#endif - static LogManager *mspInstance; - }; - - - /*************************************************************************** - * Operators, Helper - ***************************************************************************/ - - #ifndef QT_NO_DEBUG_STREAM - /*! - * \relates LogManager - * - * Writes all object member variables to the given debug stream \a rDebug and - * returns the stream. - * - * - * %LogManager(loggerrepository:Hierarchy(loggers:6 root-level:"DEBUG" - * root-appenders:0 log-level: "NULL" log-appenders:0 - * qt-level: "NULL" qt-appenders:0 handleqtmessages: false ) - * - * \sa QDebug - */ - QDebug operator<<(QDebug debug, - const LogManager &rLogManager); - #endif // QT_NO_DEBUG_STREAM - - - /************************************************************************** - * Inline - **************************************************************************/ - - inline LoggerRepository *LogManager::loggerRepository() - { // QMutexLocker locker(&instance()->mObjectGuard); // Constant for object lifetime - return instance()->mpLoggerRepository; } - - inline bool LogManager::handleQtMessages() - { // QMutexLocker locker(&instance()->mObjectGuard); // Read/Write of bool is safe - return instance()->mHandleQtMessages; } - - inline Logger *LogManager::logLogger() - { // QMutexLocker locker(&instance()->mObjectGuard); // Constant for object lifetime - return logger(QLatin1String("Log4Qt")); } - - inline Logger *LogManager::qtLogger() - { // QMutexLocker locker(&instance()->mObjectGuard); // Constant for object lifetime - return logger(QLatin1String("Qt")); } - - inline void LogManager::setHandleQtMessages(bool handleQtMessages) - { instance()->doSetHandleQtMessages(handleQtMessages); } - - inline void LogManager::configureLogLogger() - { instance()->doConfigureLogLogger(); } - - inline void LogManager::startup() - { instance()->doStartup(); } - -} // namespace Log4Qt - - -// Q_DECLARE_TYPEINFO(Log4Qt::LogManager, Q_COMPLEX_TYPE); // Use default - - -#endif // LOG4QT_LOGMANAGER_H diff --git a/src/log4qt/src/log4qt/mdc.cpp b/src/log4qt/src/log4qt/mdc.cpp deleted file mode 100644 index 5ba2ba8..0000000 --- a/src/log4qt/src/log4qt/mdc.cpp +++ /dev/null @@ -1,116 +0,0 @@ -/****************************************************************************** - * - * package: Log4Qt - * file: mdc.cpp - * created: September 2007 - * author: Martin Heinrich - * - * - * changes Feb 2009, Martin Heinrich - * - Fixed unreferenced formal parameter warning by using - * Q_UNUSED in operator<<. - * - * - * Copyright 2007 - 2009 Martin Heinrich - * - * 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. - * - *****************************************************************************/ - - - -/****************************************************************************** - * Dependencies - ******************************************************************************/ - - -#include "log4qt/mdc.h" - -#include -#include -#include -#include "log4qt/helpers/initialisationhelper.h" -#include "log4qt/logger.h" - - - -namespace Log4Qt -{ - - - /************************************************************************** - * Declarations - **************************************************************************/ - - - - /************************************************************************** - * C helper functions - **************************************************************************/ - - - - /************************************************************************** - * Class implementation: MDC - **************************************************************************/ - - - QString MDC::get(const QString &rKey) - { - if (!instance()->mHash.hasLocalData()) - return QString(); - - return instance()->mHash.localData()->value(rKey); - } - - - QHash MDC::context() - { - if (!instance()->mHash.hasLocalData()) - return QHash(); - - return *instance()->mHash.localData(); - } - - - LOG4QT_IMPLEMENT_INSTANCE(MDC) - - - QHash *MDC::localData() - { - if (!instance()->mHash.hasLocalData()) - instance()->mHash.setLocalData(new QHash); - return instance()->mHash.localData(); - } - - - - /************************************************************************** - * Implementation: Operators, Helper - **************************************************************************/ - - -#ifndef QT_NO_DEBUG_STREAM - QDebug operator<<(QDebug debug, const MDC &rMDC) - { - Q_UNUSED(rMDC); // To avoid warning C4100 on VS 2008 - debug.nospace() << "MDC(" - << "thread:" << QThread::currentThread()->objectName() << " " - << "context:" << rMDC.context() - << ")"; - return debug.space(); - } -#endif // QT_NO_DEBUG_STREAM - - -} // namespace Log4Qt diff --git a/src/log4qt/src/log4qt/mdc.h b/src/log4qt/src/log4qt/mdc.h deleted file mode 100644 index 5e8fce9..0000000 --- a/src/log4qt/src/log4qt/mdc.h +++ /dev/null @@ -1,122 +0,0 @@ -/****************************************************************************** - * - * package: Log4Qt - * file: mdc.h - * created: September 2007 - * author: Martin Heinrich - * - * - * Copyright 2007 Martin Heinrich - * - * 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. - * - ******************************************************************************/ - -#ifndef LOG4QT_MDC_H -#define LOG4QT_MDC_H - - -/****************************************************************************** - * Dependencies - ******************************************************************************/ - -#include -#include -#include -#include "log4qt/log4qt.h" - - -/****************************************************************************** - * Declarations - ******************************************************************************/ - -namespace Log4Qt -{ - - -/*! - * \brief The class MDC implements a mapped diagnostic context. - * - * \note All the functions declared in this class are thread-safe. - */ - class MDC - { - private: - MDC(); - MDC(const MDC &rOther); // Not implemented - // virtual ~MDC(); // Use compiler default - MDC &operator=(const MDC &rOther); // Not implemented - - public: - static QString get(const QString &rKey); - static QHash context(); - - /*! - * Returns the MDC instance. - */ - static MDC *instance(); - - static void put(const QString &rKey, const QString &rValue); - static void remove(const QString &rKey); - - private: - static QHash *localData(); - - private: - QThreadStorage< QHash * > mHash; - }; - - - /************************************************************************** - * Operators, Helper - **************************************************************************/ - - #ifndef QT_NO_DEBUG_STREAM - /*! - * \relates MDC - * - * Writes all object member variables to the given debug stream \a rDebug - * and returns the stream. - * - * - * %MDC(thread:"main" context:QHash(("login", "Peter")("database", "UAT")) ) - * - * \sa QDebug - */ - QDebug operator<<(QDebug debug, - const MDC &rMDC); - #endif // QT_NO_DEBUG_STREAM - - - /************************************************************************** - * Inline - **************************************************************************/ - - inline MDC::MDC() : - mHash() - {} - - inline void MDC::put(const QString &rKey, const QString &rValue) - { localData()->insert(rKey, rValue); } - - inline void MDC::remove(const QString &rKey) - { localData()->remove(rKey); } - - -} // namespace Log4Qt - - -// Q_DECLARE_TYPEINFO(Log4Qt::MDC, Q_COMPLEX_TYPE); // Use default - - -#endif // LOG4QT_MDC_H diff --git a/src/log4qt/src/log4qt/ndc.cpp b/src/log4qt/src/log4qt/ndc.cpp deleted file mode 100644 index 17ebd47..0000000 --- a/src/log4qt/src/log4qt/ndc.cpp +++ /dev/null @@ -1,154 +0,0 @@ -/****************************************************************************** - * - * package: Log4Qt - * file: ndc.cpp - * created: September 2007 - * author: Martin Heinrich - * - * - * changes Feb 2009, Martin Heinrich - * - Fixed VS 2008 unreferenced formal parameter warning by using - * Q_UNUSED in operator<<. - * - * - * Copyright 2007 - 2009 Martin Heinrich - * - * 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. - * - *****************************************************************************/ - - - -/****************************************************************************** - * Dependencies - ******************************************************************************/ - - -#include "log4qt/ndc.h" - -#include -#include -#include -#include "log4qt/helpers/initialisationhelper.h" -#include "log4qt/logger.h" - - - -namespace Log4Qt -{ - - - /************************************************************************** - * Declarations - **************************************************************************/ - - - - /************************************************************************** - * C helper functions - **************************************************************************/ - - - LOG4QT_DECLARE_STATIC_LOGGER(logger, Log4Qt:NDC) - - - - /************************************************************************** - * Class implementation: NDC - **************************************************************************/ - - - void NDC::clear() - { - if (!instance()->mStack.hasLocalData()) - return; - - instance()->mStack.localData()->clear(); - } - - - int NDC::depth() - { - if (!instance()->mStack.hasLocalData()) - return 0; - - return instance()->mStack.localData()->count(); - } - - - LOG4QT_IMPLEMENT_INSTANCE(NDC) - - - QString NDC::pop() - { - if (!instance()->mStack.hasLocalData() || instance()->mStack.localData()->isEmpty()) - { - logger()->warn("Requesting pop from empty NDC stack"); - return QString(); - } - - return instance()->mStack.localData()->pop(); - } - - - void NDC::push(const QString &rMessage) - { - if (!instance()->mStack.hasLocalData()) - instance()->mStack.setLocalData(new QStack); - - instance()->mStack.localData()->push(rMessage); - } - - - void NDC::setMaxDepth(int maxDepth) - { - if (!instance()->mStack.hasLocalData() || - instance()->mStack.localData()->size() <= maxDepth) - return; - - instance()->mStack.localData()->resize(maxDepth); - } - - - QString NDC::peek() - { - if (!instance()->mStack.hasLocalData() || - instance()->mStack.localData()->isEmpty()) - return QString(); - - return instance()->mStack.localData()->top(); - } - - - - /************************************************************************** - * Implementation: Operators, Helper - **************************************************************************/ - - -#ifndef QT_NO_DEBUG_STREAM - QDebug operator<<(QDebug debug, - const NDC &rNDC) - { - Q_UNUSED(rNDC); // To avoid warning C4100 on VS 2008 - debug.nospace() << "NDC(" - << "thread:" << QThread::currentThread()->objectName() << " " - << "peek:" << rNDC.peek() << " " - << "depth:" << rNDC.depth() - << ")"; - return debug.space(); - } -#endif // QT_NO_DEBUG_STREAM - - -} // namespace Log4Qt diff --git a/src/log4qt/src/log4qt/ndc.h b/src/log4qt/src/log4qt/ndc.h deleted file mode 100644 index e2c4210..0000000 --- a/src/log4qt/src/log4qt/ndc.h +++ /dev/null @@ -1,121 +0,0 @@ -/****************************************************************************** - * - * package: Log4Qt - * file: ndc.h - * created: September 2007 - * author: Martin Heinrich - * - * - * Copyright 2007 Martin Heinrich - * - * 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. - * - ******************************************************************************/ - -#ifndef LOG4QT_NDC_H -#define LOG4QT_NDC_H - - -/****************************************************************************** - * Dependencies - ******************************************************************************/ - -#include -#include -#include -#include "log4qt/log4qt.h" - - -/****************************************************************************** - * Declarations - ******************************************************************************/ - -namespace Log4Qt -{ - - /*! - * \brief The class NDC implements a nested diagnostic context. - * - * The method remove() is not required. QThreadStorage cleans up on thread - * exit. - * - * \note All the functions declared in this class are thread-safe. - */ - class NDC - { - private: - NDC(); - NDC(const NDC &rOther); // Not implemented - // virtual ~NDC(); // Use compiler default - NDC &operator=(const NDC &rOther); // Not implemented - - public: - static void clear(); - // JAVA: static QStack cloneStack(); - // JAVA: static QString get(); - static int depth(); - // JAVA: inherit(Stack stack) - - /*! - * Returns the NDC instance. - */ - static NDC *instance(); - - static QString pop(); - static void push(const QString &rMessage); - // JAVA: static void remove(); // Not required - static void setMaxDepth(int maxDepth); - static QString peek(); - - private: - QThreadStorage< QStack * > mStack; - }; - - - /****************************************************************************** - * Operators, Helper - ******************************************************************************/ - - #ifndef QT_NO_DEBUG_STREAM - /*! - * \relates NDC - * - * Writes all object member variables to the given debug stream \a rDebug and - * returns the stream. - * - * - * %NDC(thread:"main" peek:"i = 3" depth:4) - * - * \sa QDebug - */ - QDebug operator<<(QDebug debug, - const NDC &rNDC); - #endif // QT_NO_DEBUG_STREAM - - - /****************************************************************************** - * Inline - ******************************************************************************/ - - inline NDC::NDC() : - mStack() - {} - - -} // namespace Log4Qt - - -// Q_DECLARE_TYPEINFO(Log4Qt::NDC, Q_COMPLEX_TYPE); // Use default - - -#endif // LOG4QT_NDC_H diff --git a/src/log4qt/src/log4qt/patternlayout.cpp b/src/log4qt/src/log4qt/patternlayout.cpp deleted file mode 100644 index a93099f..0000000 --- a/src/log4qt/src/log4qt/patternlayout.cpp +++ /dev/null @@ -1,147 +0,0 @@ -/****************************************************************************** - * - * package: Log4Qt - * file: patternlayout.cpp - * created: September 2007 - * author: Martin Heinrich - * - * - * Copyright 2007 Martin Heinrich - * - * 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. - * - ******************************************************************************/ - - - -/****************************************************************************** - * Dependencies - ******************************************************************************/ - - -#include "log4qt/patternlayout.h" - -#include -#include "log4qt/helpers/patternformatter.h" -#include "log4qt/loggingevent.h" - - - -namespace Log4Qt -{ - - - /************************************************************************** - * Declarations - **************************************************************************/ - - - - /************************************************************************** - * C helper functions - **************************************************************************/ - - - - /************************************************************************** - * Class implementation: PatternLayout - **************************************************************************/ - - - PatternLayout::PatternLayout(QObject *pParent) : - Layout(pParent), - mPattern(), - mpPatternFormatter(0) - { - setConversionPattern(DEFAULT_CONVERSION_PATTERN); - } - - - PatternLayout::PatternLayout(const QString &rPattern, - QObject *pParent) : - Layout(pParent), - mPattern(), - mpPatternFormatter(0) - { - setConversionPattern(rPattern); - } - - - PatternLayout::PatternLayout(ConversionPattern conversionPattern, - QObject *pParent) : - Layout(pParent), - mPattern(), - mpPatternFormatter(0) - { - setConversionPattern(conversionPattern); - } - - - PatternLayout::~PatternLayout() - { - delete mpPatternFormatter; - } - - - void PatternLayout::setConversionPattern(ConversionPattern conversionPattern) - { - switch (conversionPattern) - { - case DEFAULT_CONVERSION_PATTERN: - setConversionPattern(QLatin1String("%m%n")); - break; - case TTCC_CONVERSION_PATTERN: - setConversionPattern(QLatin1String("%r [%t] %p %c %x - %m%n")); - break; - default: - Q_ASSERT_X(false, "PatternLayout::setConversionFormat", "Unkown ConversionFormat"); - setConversionPattern(QString()); - } - } - - - QString PatternLayout::format(const LoggingEvent &rEvent) - { - Q_ASSERT_X(mpPatternFormatter, "PatternLayout::format()", "mpPatternConverter must not be null"); - - return mpPatternFormatter->format(rEvent); - } - - - void PatternLayout::updatePatternFormatter() - { - delete mpPatternFormatter; - mpPatternFormatter = new PatternFormatter(mPattern); - } - - -#ifndef QT_NO_DEBUG_STREAM - QDebug PatternLayout::debug(QDebug &rDebug) const - { - rDebug.nospace() << "PatternLayout(" - << "name:" << name() << " " - << "pattern:" << conversionPattern() << " " - << "referencecount:" << referenceCount() - << ")"; - return rDebug.space(); - } -#endif // QT_NO_DEBUG_STREAM - - - - /************************************************************************** - * Implementation: Operators, Helper - **************************************************************************/ - - -} // namespace Log4Qt diff --git a/src/log4qt/src/log4qt/patternlayout.h b/src/log4qt/src/log4qt/patternlayout.h deleted file mode 100644 index 2152f4b..0000000 --- a/src/log4qt/src/log4qt/patternlayout.h +++ /dev/null @@ -1,159 +0,0 @@ -/****************************************************************************** - * - * package: Log4Qt - * file: patternlayout.h - * created: September 2007 - * author: Martin Heinrich - * - * - * Copyright 2007 Martin Heinrich - * - * 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. - * - ******************************************************************************/ - -#ifndef LOG4QT_PATTERNLAYOUT_H -#define LOG4QT_PATTERNLAYOUT_H - - -/****************************************************************************** - * Dependencies - ******************************************************************************/ - -#include "log4qt/layout.h" - - -/****************************************************************************** - * Declarations - ******************************************************************************/ - - -namespace Log4Qt -{ - - class PatternFormatter; - - /*! - * \brief The class PatternLayout outputs a logging event based on a - * pattern string. - * - * \note The ownership and lifetime of objects of this class are managed. - * See \ref Ownership "Object ownership" for more details. - */ - class PatternLayout : public Layout - { - Q_OBJECT - - /*! - * The property holds the conversion pattern used by the appender. - * - * The default is "%m%n". - * - * \sa conversionPattern(), setConversionPattern() - */ - Q_PROPERTY(QString conversionPattern READ conversionPattern WRITE setConversionPattern) - - public: - /*! - * The enum ConversionPattern defines constants for pattern strings. - * - * \sa setConversionPattern(ConversionPattern); - */ - enum ConversionPattern - { - /*! The default conversion pattern string is "%m,%n". */ - DEFAULT_CONVERSION_PATTERN, - /*! - * The ttcc conversion pattern string is - * "%r [%t] %p %c %x - %m%n". - */ - TTCC_CONVERSION_PATTERN, - }; - Q_ENUMS(ConversionPattern) - - PatternLayout(QObject *pParent = 0); - PatternLayout(const QString &rPattern, - QObject *pParent = 0); - - /*! - * Creates a PatternLayout with the conversion pattern value specified - * by the \a conversionPattern constant. - */ - PatternLayout(ConversionPattern conversionPattern, - QObject *pParent = 0); - - virtual ~PatternLayout(); - private: - PatternLayout(const PatternLayout &rOther); // Not implemented - PatternLayout &operator=(const PatternLayout &rOther); // Not implemented - - public: - QString conversionPattern() const; - void setConversionPattern(const QString &rPattern); - - /*! - * Sets the conversion pattern to the value specified by the - * \a conversionPattern constant. - */ - void setConversionPattern(ConversionPattern conversionPattern); - - virtual QString format(const LoggingEvent &rEvent); - - protected: -#ifndef QT_NO_DEBUG_STREAM - /*! - * Writes all object member variables to the given debug stream - * \a rDebug and returns the stream. - * - * - * %PatternLayout(name:"PL" pattern:"%r [%t] %p %c %x - %m%n" - * "referencecount:3") - * - * \sa QDebug, operator<<(QDebug debug, const LogObject &rLogObject) - */ - virtual QDebug debug(QDebug &rDebug) const; -#endif // QT_NO_DEBUG_STREAM - - private: - void updatePatternFormatter(); - - private: - QString mPattern; - PatternFormatter *mpPatternFormatter; - }; - - - /************************************************************************** - * Operators, Helper - **************************************************************************/ - - - /************************************************************************** - * Inline - **************************************************************************/ - - inline QString PatternLayout::conversionPattern() const - { return PatternLayout::mPattern; } - - inline void PatternLayout::setConversionPattern(const QString &rPattern) - { mPattern = rPattern; - updatePatternFormatter(); } - - -} // namespace Log4Qt - - -// Q_DECLARE_TYPEINFO(Log4Qt::PatternLayout, Q_COMPLEX_TYPE); // Use default - - -#endif // LOG4QT_PATTERNLAYOUT_H diff --git a/src/log4qt/src/log4qt/propertyconfigurator.cpp b/src/log4qt/src/log4qt/propertyconfigurator.cpp deleted file mode 100644 index 19b7113..0000000 --- a/src/log4qt/src/log4qt/propertyconfigurator.cpp +++ /dev/null @@ -1,588 +0,0 @@ -/****************************************************************************** - * - * package: Logging - * file: propertyconfigurator.cpp - * created: September 2007 - * author: Martin Heinrich - * - * - * changes Feb 2009, Martin Heinrich - * - Fixed VS 2008 unreferenced formal parameter warning by using - * Q_UNUSED in operator<<. - * - * - * Copyright 2007 - 2009 Martin Heinrich - * - * 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. - * - ******************************************************************************/ - - - -/****************************************************************************** - * Dependencies - ******************************************************************************/ - - -#include "log4qt/propertyconfigurator.h" - -#include -#include -#include "log4qt/helpers/configuratorhelper.h" -#include "log4qt/helpers/factory.h" -#include "log4qt/helpers/optionconverter.h" -#include "log4qt/helpers/properties.h" -#include "log4qt/appender.h" -#include "log4qt/layout.h" -#include "log4qt/logger.h" -#include "log4qt/logmanager.h" -#include "log4qt/loggerrepository.h" -#include "log4qt/varia/listappender.h" - - - -namespace Log4Qt -{ - - - /************************************************************************** - * Declarations - **************************************************************************/ - - - - /************************************************************************** - * C helper functions - **************************************************************************/ - - - LOG4QT_DECLARE_STATIC_LOGGER(logger, Log4Qt::PropertyConfigurator) - - - - /************************************************************************** - * Class implementation: PropertyConfigurator - **************************************************************************/ - - - bool PropertyConfigurator::doConfigure(const Properties &rProperties, - LoggerRepository *pLoggerRepository) - { - startCaptureErrors(); - configureFromProperties(rProperties, pLoggerRepository); - return stopCaptureErrors(); - } - - - bool PropertyConfigurator::doConfigure(const QString &rConfigFileName, - LoggerRepository *pLoggerRepository) - { - startCaptureErrors(); - configureFromFile(rConfigFileName, pLoggerRepository); - return stopCaptureErrors(); - } - - - bool PropertyConfigurator::doConfigure(const QSettings &rSettings, - LoggerRepository *pLoggerRepository) - { - startCaptureErrors(); - configureFromSettings(rSettings, pLoggerRepository); - return stopCaptureErrors(); - } - - - bool PropertyConfigurator::configure(const Properties &rProperties) - { - PropertyConfigurator configurator; - return configurator.doConfigure(rProperties); - } - - - bool PropertyConfigurator::configure(const QString &rConfigFilename) - { - PropertyConfigurator configurator; - return configurator.doConfigure(rConfigFilename); - } - - - bool PropertyConfigurator::configure(const QSettings &rSettings) - { - PropertyConfigurator configurator; - return configurator.doConfigure(rSettings); - } - - - bool PropertyConfigurator::configureAndWatch(const QString &rConfigFileName) - { - // Stop an existing watch to avoid a possible concurrent configuration - ConfiguratorHelper::setConfigurationFile(); - if (rConfigFileName.isEmpty()) - return true; - - PropertyConfigurator configurator; - bool result = configurator.doConfigure(rConfigFileName); - ConfiguratorHelper::setConfigurationFile(rConfigFileName, configure); - return result; - } - - - void PropertyConfigurator::configureFromFile(const QString &rConfigFileName, - LoggerRepository *pLoggerRepository) - { - QFile file(rConfigFileName); - if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) - { - LogError e = LOG4QT_ERROR(QT_TR_NOOP("Unable to open property file '%1'"), - CONFIGURATOR_OPENING_FILE_ERROR, - "Log4Qt::PropertyConfigurator"); - e << rConfigFileName; - e.addCausingError(LogError(file.errorString(), file.error())); - logger()->error(e); - return; - } - Properties properties; - properties.load(&file); - if (file.error()) - { - LogError e = LOG4QT_ERROR(QT_TR_NOOP("Unable to read property file '%1'"), - CONFIGURATOR_READING_FILE_ERROR, - "Log4Qt::PropertyConfigurator"); - e << rConfigFileName; - e.addCausingError(LogError(file.errorString(), file.error())); - logger()->error(e); - return; - } - configureFromProperties(properties, pLoggerRepository); - } - - - void PropertyConfigurator::configureFromProperties(const Properties &rProperties, - LoggerRepository *pLoggerRepository) - { - if (!pLoggerRepository) - pLoggerRepository = LogManager::loggerRepository(); - - configureGlobalSettings(rProperties, pLoggerRepository); - configureRootLogger(rProperties, pLoggerRepository); - configureNonRootElements(rProperties, pLoggerRepository); - mAppenderRegistry.clear(); - } - - - void PropertyConfigurator::configureFromSettings(const QSettings &rSettings, - LoggerRepository *pLoggerRepository) - { - Properties properties; - properties.load(rSettings); - configureFromProperties(properties, pLoggerRepository); - } - - - void PropertyConfigurator::configureGlobalSettings(const Properties &rProperties, - LoggerRepository *pLoggerRepository) const - { - Q_ASSERT_X(pLoggerRepository, "PropertyConfigurator::configureGlobalSettings()", "pLoggerRepository must not be null."); - - const QLatin1String key_reset("log4j.reset"); - const QLatin1String key_debug("log4j.Debug"); - const QLatin1String key_config_debug("log4j.configDebug"); - const QLatin1String key_threshold("log4j.threshold"); - const QLatin1String key_handle_qt_messages("log4j.handleQtMessages"); - - // Test each global setting and set it - // - Reset: log4j.reset - // - Debug: log4j.Debug, log4j.configDebug - // - Threshold: log4j.threshold - // - Handle Qt Messages: log4j.handleQtMessages - - // Reset - QString value = rProperties.property(key_reset); - if (!value.isEmpty() && OptionConverter::toBoolean(value, false)) - { - // Use LogManager and not pLoggerRepository to reset internal - // logging. - LogManager::resetConfiguration(); - logger()->debug("Reset configuration"); - } - - // Debug - value = rProperties.property(key_debug); - if (value.isNull()) - { - value = rProperties.property(key_config_debug); - if (!value.isNull()) - logger()->warn("[%1] is deprecated. Use [%2] instead.", key_config_debug, key_debug); - } - if (!value.isNull()) - { - // Don't use OptionConverter::toLevel(). Invalid level string is a valid setting - bool ok; - Level level = Level::fromString(value, &ok); - if (!ok) - level = Level::DEBUG_INT; - LogManager::logLogger()->setLevel(level); - logger()->debug("Set level for Log4Qt logging to %1", - LogManager::logLogger()->level().toString()); - } - - // Threshold - value = rProperties.property(key_threshold); - if (!value.isNull()) - { - pLoggerRepository->setThreshold(OptionConverter::toLevel(value, Level::ALL_INT)); - logger()->debug("Set threshold for LoggerRepository to %1", - pLoggerRepository->threshold().toString()); - } - - // Handle Qt messages - value = rProperties.property(key_handle_qt_messages); - if (!value.isNull()) - { - LogManager::setHandleQtMessages(OptionConverter::toBoolean(value, false)); - logger()->debug("Set handling of Qt messages LoggerRepository to %1", - QVariant(LogManager::handleQtMessages()).toString()); - } - } - - - void PropertyConfigurator::configureNonRootElements(const Properties &rProperties, - LoggerRepository *pLoggerRepository) - { - Q_ASSERT_X(pLoggerRepository, "PropertyConfigurator::configureNonRootElements()", "pLoggerRepository must not be null."); - - const QString logger_prefix = QLatin1String("log4j.logger."); - const QString category_prefix = QLatin1String("log4j.category."); - - // Iterate through all entries: - // - Test for the logger/category prefix - // - Convert JAVA class names to C++ ones - // - Parse logger data (Level, Appender) - // - Parse logger additivity - - QStringList keys = rProperties.propertyNames(); - QString key; - Q_FOREACH(key, keys) - { - QString java_name; - if (key.startsWith(logger_prefix)) - java_name = key.mid(logger_prefix.length()); - else if (key.startsWith(category_prefix)) - java_name = key.mid(category_prefix.length()); - QString cpp_name = OptionConverter::classNameJavaToCpp(java_name); - if (!java_name.isEmpty()) - { - Logger *p_logger = pLoggerRepository->logger(cpp_name); - QString value = OptionConverter::findAndSubst(rProperties, key); - parseLogger(rProperties, p_logger, key, value); - parseAdditivityForLogger(rProperties, p_logger, java_name); - } - } - } - - - void PropertyConfigurator::configureRootLogger(const Properties &rProperties, - LoggerRepository *pLoggerRepository) - { - Q_ASSERT_X(pLoggerRepository, "PropertyConfigurator::configureRootLogger()", "pLoggerRepository must not be null."); - - const QLatin1String key_root_logger("log4j.rootLogger"); - const QLatin1String key_root_category("log4j.rootCategory"); - - // - Test for the logger/category prefix - // - Parse logger data for root logger - - QString key = key_root_logger; - QString value = OptionConverter::findAndSubst(rProperties, key); - if (value.isNull()) - { - key = key_root_category; - value = OptionConverter::findAndSubst(rProperties, key); - if (!value.isNull()) - logger()->warn("[%1] is deprecated. Use [%2] instead.", key_root_category, key_root_logger); - } - - if (value.isNull()) - logger()->debug("Could not find root logger information. Is this correct?"); - else - parseLogger(rProperties, pLoggerRepository->rootLogger(), key, value); - } - - - void PropertyConfigurator::parseAdditivityForLogger(const Properties &rProperties, - Logger *pLogger, - const QString &rLog4jName) const - { - Q_ASSERT_X(pLogger, "parseAdditivityForLogger()", "pLogger must not be null."); - - const QLatin1String additivity_prefix("log4j.additivity."); - - // - Lookup additivity key for logger - // - Set additivity, if specified - - QString key = additivity_prefix + rLog4jName; - QString value = OptionConverter::findAndSubst(rProperties, key); - logger()->debug("Parsing additivity for logger: key '%1', value '%2'", key, value); - if (!value.isEmpty()) - { - bool additivity = OptionConverter::toBoolean(value, true); - logger()->debug("Setting additivity for logger '%1' to '%2'", pLogger->name(), QVariant(value).toString()); - pLogger->setAdditivity(additivity); - } - } - - - LogObjectPtr PropertyConfigurator::parseAppender(const Properties &rProperties, - const QString &rName) - { - // - Test if appender has been parsed before - // - Find appender key - // - Create appender object - // - Set layout, if required by appender - // - Set properties - // - Activate options - // - Add appender to registry - - const QLatin1String appender_prefix("log4j.appender."); - - logger()->debug("Parsing appender named '%1'", rName); - - if (mAppenderRegistry.contains(rName)) - { - logger()->debug("Appender '%1' was already parsed.", rName); - return mAppenderRegistry.value(rName); - } - - QString key = appender_prefix + rName; - QString value = OptionConverter::findAndSubst(rProperties, key); - if (value.isNull()) - { - LogError e = LOG4QT_ERROR(QT_TR_NOOP("Missing appender definition for appender named '%1'"), - CONFIGURATOR_MISSING_APPENDER_ERROR, - "Log4Qt::PropertyConfigurator"); - e << rName; - logger()->error(e); - return 0; - } - LogObjectPtr p_appender = Factory::createAppender(value); - if (!p_appender) - { - LogError e = LOG4QT_ERROR(QT_TR_NOOP("Unable to create appender of class '%1' namd '%2'"), - CONFIGURATOR_UNKNOWN_APPENDER_CLASS_ERROR, - "Log4Qt::PropertyConfigurator"); - e << value << rName; - logger()->error(e); - return 0; - } - p_appender->setName(rName); - - if (p_appender->requiresLayout()) - { - LogObjectPtr p_layout = parseLayout(rProperties, key); - if (p_layout) - p_appender->setLayout(p_layout); - else - return 0; - } - - QStringList exclusions; - exclusions << QLatin1String("layout"); - setProperties(rProperties, key + QLatin1String("."), exclusions, p_appender); - AppenderSkeleton *p_appenderskeleton = qobject_cast(p_appender); - if (p_appenderskeleton) - p_appenderskeleton->activateOptions(); - - mAppenderRegistry.insert(rName, p_appender); - return p_appender; - } - - - LogObjectPtr PropertyConfigurator::parseLayout(const Properties &rProperties, - const QString &rAppenderKey) - { - Q_ASSERT_X(!rAppenderKey.isEmpty(), "PropertyConfigurator::parseLayout()", "rAppenderKey must not be empty."); - - // - Find layout key - // - Create layput object - // - Set properties - // - Activate options - - const QLatin1String layout_suffix(".layout"); - - logger()->debug("Parsing layout for appender named '%1'", rAppenderKey); - - QString key = rAppenderKey + layout_suffix; - QString value = OptionConverter::findAndSubst(rProperties, key); - if (value.isNull()) - { - LogError e = LOG4QT_ERROR(QT_TR_NOOP("Missing layout definition for appender '%1'"), - CONFIGURATOR_MISSING_LAYOUT_ERROR, - "Log4Qt::PropertyConfigurator"); - e << rAppenderKey; - logger()->error(e); - return 0; - } - LogObjectPtr p_layout = Factory::createLayout(value); - if (!p_layout) - { - LogError e = LOG4QT_ERROR(QT_TR_NOOP("Unable to create layoput of class '%1' requested by appender '%2'"), - CONFIGURATOR_UNKNOWN_LAYOUT_CLASS_ERROR, - "Log4Qt::PropertyConfigurator"); - e << value << rAppenderKey; - logger()->error(e); - return 0; - } - - QStringList exclusions; - setProperties(rProperties, key + QLatin1String("."), QStringList(), p_layout); - p_layout->activateOptions(); - - return p_layout; - } - - - void PropertyConfigurator::parseLogger(const Properties &rProperties, - Logger *pLogger, - const QString &rKey, - const QString &rValue) - { - Q_ASSERT_X(pLogger, "PropertyConfigurator::parseLogger()", "pLogger must not be null."); - Q_ASSERT_X(!rKey.isEmpty(), "PropertyConfigurator::parseLogger()", "rKey must not be empty."); - - const QLatin1String keyword_inherited("INHERITED"); - - // - Split value on comma - // - If level value, is specified - // - Test for NULL and INHERITED - // - Ensure root logger is not set to NULL - // - Set level - // - For each entry - // - Create Appender - - logger()->debug("Parsing logger: key '%1', value '%2'", rKey, rValue); - QStringList appenders = rValue.split(QLatin1Char(',')); - QStringListIterator i (appenders); - - // First entry is the level. There will be always one entry, even if the rValue is - // empty or does not contain a comma. - QString value = i.next().trimmed(); - if (!value.isEmpty()) - { - Level level; - if (value.compare(keyword_inherited,Qt::CaseInsensitive) == 0) - level = Level::NULL_INT; - else - level = OptionConverter::toLevel(value, Level::DEBUG_INT); - if (level == Level::NULL_INT && pLogger->name() == QString()) - logger()->warn("The root logger level cannot be set to NULL."); - else - { - pLogger->setLevel(level); - logger()->debug("Set level for logger '%1' to '%2'", - pLogger->name(), pLogger->level().toString()); - } - } - - pLogger->removeAllAppenders(); - while(i.hasNext()) - { - value = i.next().trimmed(); - if(value.isEmpty()) - continue; - LogObjectPtr p_appender = parseAppender(rProperties, value); - if (p_appender) - pLogger->addAppender(p_appender); - } - } - - - void PropertyConfigurator::setProperties(const Properties &rProperties, - const QString &rPrefix, - const QStringList &rExclusions, - QObject *pObject) - { - Q_ASSERT_X(!rPrefix.isEmpty(), "PropertyConfigurator::setProperties()", "rPrefix must not be empty."); - Q_ASSERT_X(pObject, "PropertyConfigurator::setProperties()", "pObject must not be null."); - - // Iterate through all entries: - // - Test for prefix to determine, if setting is for object - // - Skip empty property name - // - Skip property names in exclusion list - // - Set property on object - - logger()->debug("Setting properties for object of class '%1' from keys starting with '%2'", - QLatin1String(pObject->metaObject()->className()), - rPrefix); - - QStringList keys = rProperties.propertyNames(); - QString key; - Q_FOREACH(key, keys) - { - if (!key.startsWith(rPrefix)) - continue; - QString property = key.mid(rPrefix.length()); - if (property.isEmpty()) - continue; - QStringList split_property = property.split(QLatin1Char('.')); - if (rExclusions.contains(split_property.at(0), Qt::CaseInsensitive)) - continue; - QString value = OptionConverter::findAndSubst(rProperties, key); - Factory::setObjectProperty(pObject, property, value); - } - } - - - void PropertyConfigurator::startCaptureErrors() - { - Q_ASSERT_X(!mpConfigureErrors, "PropertyConfigurator::startCaptureErrors()", "mpConfigureErrors must be empty."); - - mpConfigureErrors = new ListAppender; - mpConfigureErrors->setName(QLatin1String("PropertyConfigurator")); - mpConfigureErrors->setConfiguratorList(true); - mpConfigureErrors->setThreshold(Level::ERROR_INT); - LogManager::logLogger()->addAppender(mpConfigureErrors); - } - - - bool PropertyConfigurator::stopCaptureErrors() - { - Q_ASSERT_X(mpConfigureErrors, "PropertyConfigurator::stopCaptureErrors()", "mpConfigureErrors must not be empty."); - - LogManager::logLogger()->removeAppender(mpConfigureErrors); - ConfiguratorHelper::setConfigureError(mpConfigureErrors->list()); - bool result = (mpConfigureErrors->list().count() == 0); - mpConfigureErrors = 0; - return result; - } - - - - /************************************************************************** - * Implementation: Operators, Helper - **************************************************************************/ - - -#ifndef QT_NO_DEBUG_STREAM - QDebug operator<<(QDebug debug, - const PropertyConfigurator &rPropertyConfigurator) - { - Q_UNUSED(rPropertyConfigurator); - debug.nospace() << "PropertyConfigurator(" - << ")"; - return debug.space(); - } -#endif - - - -} // namespace Logging diff --git a/src/log4qt/src/log4qt/propertyconfigurator.h b/src/log4qt/src/log4qt/propertyconfigurator.h deleted file mode 100644 index ddf45e5..0000000 --- a/src/log4qt/src/log4qt/propertyconfigurator.h +++ /dev/null @@ -1,194 +0,0 @@ -/****************************************************************************** - * - * package: Logging - * file: propertyconfigurator.h - * created: September 2007 - * author: Martin Heinrich - * - * - * Copyright 2007 Martin Heinrich - * - * 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. - * - ******************************************************************************/ - -#ifndef LOG4QT_PROPERTYCONFIGURATOR_H -#define LOG4QT_PROPERTYCONFIGURATOR_H - - -/****************************************************************************** - * Dependencies - ******************************************************************************/ - - -#include -#include "log4qt/helpers/logobjectptr.h" -#include "log4qt/log4qt.h" - - -/****************************************************************************** - * Declarations - ******************************************************************************/ - -class QSettings; - -namespace Log4Qt -{ - - class Appender; - class Layout; - class ListAppender; - class Logger; - class Properties; - class LoggerRepository; - - /*! - * \brief The class PropertyConfigurator allows the configuration of the - * package from a JAVA properties file. - * - * \note All the functions declared in this class are thread-safe. - */ - class PropertyConfigurator - { - public: - PropertyConfigurator(); - // virtual ~PropertyConfigurator(); // Use compiler default - private: - PropertyConfigurator(const PropertyConfigurator &rOther); // Not implemented - PropertyConfigurator &operator=(const PropertyConfigurator &rOther); // Not implemented - - public: - /*! - * \sa ConfiguratorHelper::configureError() - */ - bool doConfigure(const Properties &rProperties, - LoggerRepository *pLoggerRepository = 0); - - /*! - * \sa ConfiguratorHelper::configureError() - */ - bool doConfigure(const QString &rConfigFileName, - LoggerRepository *pLoggerRepository = 0); - - /*! - * Reads the configuration data from the QSettings object - * \a rSettings. - * - * \sa \ref Properties::load(const QSettings &) "Properties::load()", - * ConfiguratorHelper::configureError() - */ - bool doConfigure(const QSettings &rSettings, - LoggerRepository *pLoggerRepository = 0); - - // JAVA: void doConfigure(const QUrl &rUrl, LoggerRepository *pLoggerRepository); - - /*! - * \sa ConfiguratorHelper::configureError() - */ - static bool configure(const Properties &rProperties); - - /*! - * \sa ConfiguratorHelper::configureError() - */ - static bool configure(const QString &rConfigFilename); - - /*! - * Reads the configuration data from the QSettings object - * \a rSettings. - * - * \sa \ref doConfigure(const QSettings &, LoggerRepository *) "doConfigure()", - * \ref Properties::load(const QSettings &) "Properties::load()", - * ConfiguratorHelper::configureError() - */ - static bool configure(const QSettings &rSettings); - - // JAVA: static void configure(const QUrl &rUrl); - - /*! - * \sa ConfiguratorHelper::configureError(), - * ConfiguratorHelper::configurationFile() - */ - static bool configureAndWatch(const QString &rConfigFilename); - - private: - void configureFromFile(const QString &rConfigFileName, - LoggerRepository *pLoggerRepository); - void configureFromProperties(const Properties &rProperties, - LoggerRepository *pLoggerRepository); - void configureFromSettings(const QSettings &rSettings, - LoggerRepository *pLoggerRepository); - void configureGlobalSettings(const Properties &rProperties, - LoggerRepository *pLoggerRepository) const; - void configureNonRootElements(const Properties &rProperties, - LoggerRepository *pLoggerRepository); - void configureRootLogger(const Properties &rProperties, - LoggerRepository *pLoggerRepository); - void parseAdditivityForLogger(const Properties &rProperties, - Logger *pLogger, - const QString &rLog4jName) const; - LogObjectPtr parseAppender(const Properties &rProperties, - const QString &rName); - LogObjectPtr parseLayout(const Properties &rProperties, - const QString &rAppenderName); - void parseLogger(const Properties &rProperties, - Logger *pLogger, - const QString &rKey, - const QString &rValue); - void setProperties(const Properties &rProperties, - const QString &rPrefix, - const QStringList &rExclusions, - QObject *pObject); - void startCaptureErrors(); - bool stopCaptureErrors(); - - private: - LogObjectPtr mpConfigureErrors; - QHash< QString, LogObjectPtr > mAppenderRegistry; - }; - - /************************************************************************** - * Operators, Helper - **************************************************************************/ - -#ifndef QT_NO_DEBUG_STREAM - /*! - * \relates PropertyConfigurator - * - * Writes all object member variables to the given debug stream \a debug - * and returns the stream. - * - * - * %PropertyConfigurator() - * - * \sa QDebug - */ - QDebug operator<<(QDebug debug, - const PropertyConfigurator &rPropertyConfigurator); -#endif - - - /************************************************************************** - * Inline - **************************************************************************/ - - inline PropertyConfigurator::PropertyConfigurator() - {} - - -} // namspace Logging - - -// Q_DECLARE_TYPEINFO(Log4Qt::PropertyConfigurator, Q_COMPLEX_TYPE); // Use default - - -#endif // LOG4QT_PROPERTYCONFIGURATOR_H diff --git a/src/log4qt/src/log4qt/rollingfileappender.cpp b/src/log4qt/src/log4qt/rollingfileappender.cpp deleted file mode 100644 index 44f7bbe..0000000 --- a/src/log4qt/src/log4qt/rollingfileappender.cpp +++ /dev/null @@ -1,191 +0,0 @@ -/****************************************************************************** - * - * package: Log4Qt - * file: rollingfileappender.cpp - * created: September 2007 - * author: Martin Heinrich - * - * - * Copyright 2007 Martin Heinrich - * - * 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. - * - ******************************************************************************/ - - - -/****************************************************************************** - * Dependencies - ******************************************************************************/ - - -#include "log4qt/rollingfileappender.h" - -#include -#include -#include -#include "log4qt/helpers/optionconverter.h" -#include "log4qt/layout.h" -#include "log4qt/loggingevent.h" - - - -namespace Log4Qt -{ - - - /************************************************************************ - Declarations - *************************************************************************/ - - - - /************************************************************************ - C helper functions - *************************************************************************/ - - - - /************************************************************************ - Class implementation: RollingFileAppender - *************************************************************************/ - - - RollingFileAppender::RollingFileAppender(QObject *pParent) : - FileAppender(pParent), - mMaxBackupIndex(1), - mMaximumFileSize(10*1024*1024) - { - } - - - RollingFileAppender::RollingFileAppender(Layout *pLayout, - const QString &rFileName, - QObject *pParent) : - FileAppender(pLayout, rFileName, pParent), - mMaxBackupIndex(1), - mMaximumFileSize(10*1024*1024) - { - } - - - RollingFileAppender::RollingFileAppender(Layout *pLayout, - const QString &rFileName, - bool append, - QObject *pParent) : - FileAppender(pLayout, rFileName, append, pParent), - mMaxBackupIndex(1), - mMaximumFileSize(10*1024*1024) - { - } - - - RollingFileAppender::~RollingFileAppender() - { - close(); - } - - - void RollingFileAppender::setMaxFileSize(const QString &rMaxFileSize) - { - bool ok; - qint64 max_file_size = OptionConverter::toFileSize(rMaxFileSize, &ok); - if (ok) - setMaximumFileSize(max_file_size); - } - - - void RollingFileAppender::append(const LoggingEvent &rEvent) - { - // Q_ASSERT_X(, "RollingFileAppender::append()", "Lock must be held by caller") - - FileAppender::append(rEvent); - if (writer()->device()->size() > this->mMaximumFileSize) - rollOver(); - } - - - void RollingFileAppender::rollOver() - { - // Q_ASSERT_X(, "RollingFileAppender::rollOver()", "Lock must be held by caller") - - logger()->debug("Rolling over with maxBackupIndex = %1", mMaxBackupIndex); - - closeFile(); - - QFile f; - f.setFileName(file() + QLatin1Char('.') + QString::number(mMaxBackupIndex)); - if (f.exists() && !removeFile(f)) - return; - - QString target_file_name; - int i; - for (i = mMaxBackupIndex - 1; i >=1; i--) - { - f.setFileName(file() + QLatin1Char('.') + QString::number(i)); - if (f.exists()) - { - target_file_name = file() + QLatin1Char('.') + QString::number(i + 1); - if (!renameFile(f, target_file_name)) - return; - } - } - - f.setFileName(file()); - target_file_name = file() + QLatin1String(".1"); - if (!renameFile(f, target_file_name)) - return; - - openFile(); - } - - -#ifndef QT_NO_DEBUG_STREAM - QDebug RollingFileAppender::debug(QDebug &rDebug) const - { - QString layout_name; - if (layout()) - layout_name = layout()->name(); - QString codec_name; - if (encoding()) - codec_name = QLatin1String(encoding()->name()); - - rDebug.nospace() << "RollingFileAppender(" - << "name:" << name() << " " - << "appendfile:" << appendFile() << " " - << "bufferedio:" << bufferedIo() << " " - << "encoding:" << codec_name << " " - << "file:" << file() << " " - << "filter:" << firstFilter() << " " - << "immediateflush:" << immediateFlush() << " " - << "isactive:" << isActive() << " " - << "isclosed:" << isClosed() << " " - << "layout:" << layout_name << " " - << "maxbackupindex:" << maxBackupIndex() << " " - << "maximumfilesize:" << maximumFileSize() << " " - << "referencecount:" << referenceCount() << " " - << "threshold:" << threshold().toString() << " " - << "writer:" << writer() - << ")"; - return rDebug.space(); - } -#endif // QT_NO_DEBUG_STREAM - - - - /************************************************************************** - * Implementation: Operators, Helper - **************************************************************************/ - - -} // namespace Log4Qt diff --git a/src/log4qt/src/log4qt/rollingfileappender.h b/src/log4qt/src/log4qt/rollingfileappender.h deleted file mode 100644 index 0f07ad9..0000000 --- a/src/log4qt/src/log4qt/rollingfileappender.h +++ /dev/null @@ -1,164 +0,0 @@ -/****************************************************************************** - * - * package: Log4Qt - * file: rollingfileappender.h - * created: September 2007 - * author: Martin Heinrich - * - * - * Copyright 2007 Martin Heinrich - * - * 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. - * - ******************************************************************************/ - -#ifndef LOG4QT_ROLINGFILEAPPENDER_H -#define LOG4QT_ROLINGFILEAPPENDER_H - - -/****************************************************************************** - * Dependencies - ******************************************************************************/ - -#include "log4qt/fileappender.h" - - -/****************************************************************************** - * Declarations - ******************************************************************************/ - -namespace Log4Qt -{ - - /*! - * \brief The class RollingFileAppender extends FileAppender to backup - * the log files when they reach a certain size. - * - * \note All the functions declared in this class are thread-safe. - * - * \note The ownership and lifetime of objects of this class are managed. - * See \ref Ownership "Object ownership" for more details. - */ - class RollingFileAppender : public FileAppender - { - Q_OBJECT - - /*! - * The property holds the maximum backup count used by the appender. - * - * The default is 1. - * - * \sa maxBackupIndex(), setMaxBackupIndex() - */ - Q_PROPERTY(int maxBackupIndex READ maxBackupIndex WRITE setMaxBackupIndex) - - /*! - * The property holds the maximum file size used by the appender. - * - * The default is 10 MB (10 * 1024 * 1024). - * - * \sa maximumFileSize(), setMaximumFileSize() - */ - Q_PROPERTY(qint64 maximumFileSize READ maximumFileSize WRITE setMaximumFileSize) - - /*! - * The property sets the maximum file size from a string value. - * - * \sa setMaxFileSize(), maximumFileSize() - */ - Q_PROPERTY(QString maxFileSize WRITE setMaxFileSize) - - public: - RollingFileAppender(QObject *pParent = 0); - RollingFileAppender(Layout *pLayout, - const QString &rFileName, - QObject *pParent = 0); - RollingFileAppender(Layout *pLayout, - const QString &rFileName, - bool append, - QObject *pParent = 0); - virtual ~RollingFileAppender(); - private: - RollingFileAppender(const RollingFileAppender &rOther); // Not implemented - RollingFileAppender &operator=(const RollingFileAppender &rOther); // Not implemented - - public: - int maxBackupIndex() const; - qint64 maximumFileSize() const; - void setMaxBackupIndex(int maxBackupIndex); - void setMaximumFileSize(qint64 maximumFileSize); - void setMaxFileSize(const QString &rMaxFileSize); - - protected: - virtual void append(const LoggingEvent &rEvent); - -#ifndef QT_NO_DEBUG_STREAM - /*! - * Writes all object member variables to the given debug stream - * \a rDebug and returns the stream. - * - * - * %RollingFileAppender(name:"RFA" appendfile:false bufferedio:true - * encoding:"" file:"/log.txt" filter: 0x0 - * immediateflush:true isactive:true - * isclosed:false layout:"TTCC" maxbackupindex:2 - * maximumfilesize:40 referencecount:1 - * threshold:"NULL" writer:0x4175af8) - * - * \sa QDebug, operator<<(QDebug debug, const LogObject &rLogObject) - */ - virtual QDebug debug(QDebug &rDebug) const; -#endif // QT_NO_DEBUG_STREAM - - private: - void rollOver(); - - private: - int mMaxBackupIndex; - qint64 mMaximumFileSize; - }; - - - /************************************************************************** - * Operators, Helper - **************************************************************************/ - - - /************************************************************************** - * Inline - **************************************************************************/ - - inline int RollingFileAppender::maxBackupIndex() const - { QMutexLocker locker(&mObjectGuard); - return mMaxBackupIndex; } - - inline qint64 RollingFileAppender::maximumFileSize() const - { QMutexLocker locker(&mObjectGuard); - return mMaximumFileSize; } - - inline void RollingFileAppender::setMaxBackupIndex(int maxBackupIndex) - { QMutexLocker locker(&mObjectGuard); - mMaxBackupIndex = maxBackupIndex; } - - inline void RollingFileAppender::setMaximumFileSize(qint64 maximumFileSize) - { QMutexLocker locker(&mObjectGuard); - mMaximumFileSize = maximumFileSize; } - - -} // namespace Log4Qt - - -// Q_DECLARE_TYPEINFO(Log4Qt::RollingFileAppender, Q_COMPLEX_TYPE); // Use default - - -#endif // LOG4QT_ROLINGFILEAPPENDER_H diff --git a/src/log4qt/src/log4qt/simplelayout.cpp b/src/log4qt/src/log4qt/simplelayout.cpp deleted file mode 100644 index a7d5234..0000000 --- a/src/log4qt/src/log4qt/simplelayout.cpp +++ /dev/null @@ -1,84 +0,0 @@ -/****************************************************************************** - * - * package: Log4Qt - * file: simplelayout.cpp - * created: September 2007 - * author: Martin Heinrich - * - * - * Copyright 2007 Martin Heinrich - * - * 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. - * - ******************************************************************************/ - - - -/****************************************************************************** - * Dependencies - ******************************************************************************/ - - -#include "log4qt/simplelayout.h" - -#include -#include "log4qt/loggingevent.h" - - - -namespace Log4Qt -{ - - - /************************************************************************** - * Declarations - **************************************************************************/ - - - - /************************************************************************** - * C helper functions - **************************************************************************/ - - - - /************************************************************************** - * Class implementation: SimpleLayout - **************************************************************************/ - - - QString SimpleLayout::format(const LoggingEvent &rEvent) - { - return rEvent.level().toString() + QLatin1String(" - ") + rEvent.message() + Layout::endOfLine(); - } - - -#ifndef QT_NO_DEBUG_STREAM - QDebug SimpleLayout::debug(QDebug &rDebug) const - { - rDebug.nospace() << "SimpleLayout(" - << "name:" << name() << " " - << "referencecount:" << referenceCount() - << ")"; - return rDebug.space(); - } -#endif // QT_NO_DEBUG_STREAM - - - - /************************************************************************** - * Implementation: Operators, Helper - **************************************************************************/ - - -} // namespace Log4Qt diff --git a/src/log4qt/src/log4qt/simplelayout.h b/src/log4qt/src/log4qt/simplelayout.h deleted file mode 100644 index 5ebe558..0000000 --- a/src/log4qt/src/log4qt/simplelayout.h +++ /dev/null @@ -1,102 +0,0 @@ -/****************************************************************************** - * - * package: Log4Qt - * file: simplelayout.h - * created: September 2007 - * author: Martin Heinrich - * - * - * Copyright 2007 Martin Heinrich - * - * 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. - * - ******************************************************************************/ - -#ifndef LOG4QT_SIMPLELAYOUT_H -#define LOG4QT_SIMPLELAYOUT_H - - -/****************************************************************************** - * Dependencies - ******************************************************************************/ - -#include "log4qt/layout.h" - - -/****************************************************************************** - * Declarations - ******************************************************************************/ - - -namespace Log4Qt -{ - - /*! - * \brief The class SimpleLayout outputs the level and message of a logging - * event. - * - * \note The ownership and lifetime of objects of this class are managed. - * See \ref Ownership "Object ownership" for more details. - */ - class SimpleLayout : public Layout - { - Q_OBJECT - - public: - SimpleLayout(QObject *pParent = 0); - // virtual ~SimpleLayout(); // Use compiler default - private: - SimpleLayout(const SimpleLayout &rOther); // Not implemented - SimpleLayout &operator=(const SimpleLayout &rOther); // Not implemented - - public: - virtual QString format(const LoggingEvent &rEvent); - - protected: - -#ifndef QT_NO_DEBUG_STREAM - /*! - * Writes all object member variables to the given debug stream - * \a rDebug and returns the stream. - * - * - * %SimpleLayout(name:"SL" referencecount:1) - * - * \sa QDebug, operator<<(QDebug debug, const LogObject &rLogObject) - */ - virtual QDebug debug(QDebug &rDebug) const; -#endif // QT_NO_DEBUG_STREAM - }; - - - /************************************************************************** - * Operators, Helper - **************************************************************************/ - - - /************************************************************************** - * Inline - **************************************************************************/ - - inline SimpleLayout::SimpleLayout(QObject *pParent) : - Layout(pParent) - {} - - -} // namespace Log4Qt - - -// Q_DECLARE_TYPEINFO(Log4Qt::SimpleLayout, Q_COMPLEX_TYPE); // Use default - - -#endif // LOG4QT_SIMPLELAYOUT_H diff --git a/src/log4qt/src/log4qt/spi/filter.cpp b/src/log4qt/src/log4qt/spi/filter.cpp deleted file mode 100644 index 8f2d10e..0000000 --- a/src/log4qt/src/log4qt/spi/filter.cpp +++ /dev/null @@ -1,70 +0,0 @@ -/****************************************************************************** - * - * package: Log4Qt - * file: filter.cpp - * created: September 2007 - * author: Martin Heinrich - * - * - * Copyright 2007 Martin Heinrich - * - * 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. - * - ******************************************************************************/ - - - -/****************************************************************************** - * Dependencies - ******************************************************************************/ - - -#include "log4qt/spi/filter.h" - -#include - - -namespace Log4Qt -{ - - - /************************************************************************** - * Declarations - **************************************************************************/ - - - - /************************************************************************** - * C helper functions - **************************************************************************/ - - - - /************************************************************************** - * Class implementation: Filter - **************************************************************************/ - - - void Filter::setNext(Filter *pFilter) - { - mpNext = pFilter; - } - - - - /************************************************************************** - * Implementation: Operators, Helper - **************************************************************************/ - - -} // namespace Log4Qt diff --git a/src/log4qt/src/log4qt/spi/filter.h b/src/log4qt/src/log4qt/spi/filter.h deleted file mode 100644 index 0fd48f0..0000000 --- a/src/log4qt/src/log4qt/spi/filter.h +++ /dev/null @@ -1,124 +0,0 @@ -/****************************************************************************** - * - * package: Log4Qt - * file: filter.h - * created: September 2007 - * author: Martin Heinrich - * - * - * Copyright 2007 Martin Heinrich - * - * 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. - * - ******************************************************************************/ - -#ifndef LOG4QT_FILTER_H -#define LOG4QT_FILTER_H - - -/****************************************************************************** - * Dependencies - ******************************************************************************/ - -#include "log4qt/helpers/logobject.h" - -#include "log4qt/helpers/logobjectptr.h" -#include "log4qt/log4qt.h" - - -/****************************************************************************** - * Declarations - ******************************************************************************/ - -namespace Log4Qt -{ - - class LoggingEvent; - - /*! - * \brief The class Filter is the base class for all filters. - * - * \note The ownership and lifetime of objects of this class are managed. - * See \ref Ownership "Object ownership" for more details. - */ - class Filter : public LogObject - { - Q_OBJECT - - /*! - * The property holds the next filter of this filter. - * - * The default is 0 for no next filter. - * - * \sa next(), setNext() - */ - Q_PROPERTY(Filter* next READ next WRITE setNext) - - public: - enum Decision - { - ACCEPT, - DENY, - NEUTRAL - }; - Q_ENUMS(Decision); - - public: - Filter(QObject *pObject = 0); - // Filter(const Filter &rOther); // Use compiler default - virtual ~Filter(); - // Filter &operator=(const Filter &rOther); // Use compiler default - - Filter* next() const; - void setNext(Filter *pFilter); - - virtual void activateOptions(); - virtual Decision decide(const LoggingEvent &rEvent) const = 0; - - private: - LogObjectPtr mpNext; - }; - - - /************************************************************************** - * Operators, Helper - **************************************************************************/ - - - /************************************************************************** - * Inline - **************************************************************************/ - - inline Filter::Filter(QObject *pObject) : - LogObject(pObject), - mpNext(0) - {} - - inline Filter::~Filter() - {} - - inline Filter* Filter::next() const - { return mpNext; } - - inline void Filter::activateOptions() - {} - - -} // namespace Log4Qt - - -// Q_DECLARE_TYPEINFO(Log4Qt::Filter, Q_COMPLEX_TYPE); // Use default -Q_DECLARE_TYPEINFO(Log4Qt::LogObjectPtr, Q_MOVABLE_TYPE); - - -#endif // LOG4QT_FILTER_H diff --git a/src/log4qt/src/log4qt/ttcclayout.cpp b/src/log4qt/src/log4qt/ttcclayout.cpp deleted file mode 100644 index 023ba11..0000000 --- a/src/log4qt/src/log4qt/ttcclayout.cpp +++ /dev/null @@ -1,182 +0,0 @@ -/****************************************************************************** - * - * package: Log4Qt - * file: ttcclayout.cpp - * created: September 2007 - * author: Martin Heinrich - * - * - * Copyright 2007 Martin Heinrich - * - * 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. - * - ******************************************************************************/ - - - -/****************************************************************************** - * Dependencies - ******************************************************************************/ - - -#include "log4qt/ttcclayout.h" - -#include -#include -#include "log4qt/helpers/datetime.h" -#include "log4qt/helpers/patternformatter.h" -#include "log4qt/logger.h" -#include "log4qt/loggingevent.h" - - - -namespace Log4Qt -{ - - - /************************************************************************** - * Declarations - **************************************************************************/ - - - - /************************************************************************** - * C helper functions - **************************************************************************/ - - - - /************************************************************************** - * Class implementation: TTCCLayout - **************************************************************************/ - - - TTCCLayout::TTCCLayout(QObject *pParent) : - Layout(pParent), - mCategoryPrefixing(true), - mContextPrinting(true), - mDateFormat(), - mThreadPrinting(true), - mpPatternFormatter(0) - { - setDateFormat(TIME_RELATIVE); - } - - - TTCCLayout::TTCCLayout(const QString &rDateFormat, - QObject *pParent) : - Layout(pParent), - mCategoryPrefixing(true), - mContextPrinting(true), - mDateFormat(rDateFormat), - mThreadPrinting(true), - mpPatternFormatter(0) - { - } - - - TTCCLayout::TTCCLayout(DateFormat dateFormat, - QObject *pParent) : - Layout(pParent), - mCategoryPrefixing(true), - mContextPrinting(true), - mDateFormat(), - mThreadPrinting(true), - mpPatternFormatter(0) - { - setDateFormat(dateFormat); - } - - - TTCCLayout::~TTCCLayout() - { - delete mpPatternFormatter; - } - - - void TTCCLayout::setDateFormat(DateFormat dateFormat) - { - switch (dateFormat) - { - case NONE: - setDateFormat(QLatin1String("NONE")); - break; - case ISO8601: - setDateFormat(QLatin1String("ISO8601")); - break; - case TIME_ABSOLUTE: - setDateFormat(QLatin1String("TIME_ABSOLUTE")); - break; - case DATE: - setDateFormat(QLatin1String("DATE")); - break; - case TIME_RELATIVE: - setDateFormat(QLatin1String("TIME_RELATIVE")); - break; - default: - Q_ASSERT_X(false, "TTCCLayout::setDateFormat", "Unkown DateFormat"); - setDateFormat(QString()); - } - } - - - QString TTCCLayout::format(const LoggingEvent &rEvent) - { - Q_ASSERT_X(mpPatternFormatter, "TTCCLayout::format()", "mpPatternConverter must not be null"); - - return mpPatternFormatter->format(rEvent); - } - - - void TTCCLayout::updatePatternFormatter() - { - QString pattern; - - pattern += QLatin1String("%d{") + mDateFormat + QLatin1String("}"); - if (mThreadPrinting) - pattern += QLatin1String(" [%t]"); - pattern += QLatin1String(" %-5p"); - if (mCategoryPrefixing) - pattern += QLatin1String(" %c"); - if (mContextPrinting) - pattern += QLatin1String(" %x"); - pattern += QLatin1String(" - %m%n"); - - delete mpPatternFormatter; - mpPatternFormatter = new PatternFormatter(pattern); - } - - -#ifndef QT_NO_DEBUG_STREAM - QDebug TTCCLayout::debug(QDebug &rDebug) const - { - rDebug.nospace() << "TTCCLayout(" - << "name:" << name() << " " - << "categoryprefixing:" << categoryPrefixing() << " " - << "contextprinting:" << contextPrinting() << " " - << "dateformat:" << dateFormat() << " " - << "referencecount:" << referenceCount() << " " - << "threadprinting:" << threadPrinting() - << ")"; - return rDebug.space(); - } -#endif // QT_NO_DEBUG_STREAM - - - - /************************************************************************** - * Implementation: Operators, Helper - **************************************************************************/ - - -} // namespace Log4Qt diff --git a/src/log4qt/src/log4qt/ttcclayout.h b/src/log4qt/src/log4qt/ttcclayout.h deleted file mode 100644 index c147b00..0000000 --- a/src/log4qt/src/log4qt/ttcclayout.h +++ /dev/null @@ -1,235 +0,0 @@ -/****************************************************************************** - * - * package: Log4Qt - * file: ttcclayout.h - * created: September 2007 - * author: Martin Heinrich - * - * - * Copyright 2007 Martin Heinrich - * - * 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. - * - ******************************************************************************/ - -#ifndef LOG4QT_TTCCLAYOUT_H -#define LOG4QT_TTCCLAYOUT_H - - -/****************************************************************************** - * Dependencies - ******************************************************************************/ - -#include "log4qt/layout.h" - - -/****************************************************************************** - * Declarations - ******************************************************************************/ - -namespace Log4Qt -{ - - class LoggingEvent; - class PatternFormatter; - - /*! - * \brief The class TTCCLayout outputs the time, thread, logger and nested - * diagnostic context information of a logging event. - * - * \note The ownership and lifetime of objects of this class are managed. - * See \ref Ownership "Object ownership" for more details. - */ - class TTCCLayout : public Layout - { - Q_OBJECT - - /*! - * The property holds if the logger name is part of the formatted output. - * - * The default value is true for including the logger name. - * - * \sa categoryPrefixing(), setCategoryPrefixing() - */ - Q_PROPERTY(bool categoryPrefixing READ categoryPrefixing WRITE setCategoryPrefixing) - - /*! - * The property holds if the nested context information is part of the - * formatted output. - * - * The default value it true for including the nested context information. - * - * \sa contextPrinting(), setContextPrinting() - */ - Q_PROPERTY(bool contextPrinting READ contextPrinting WRITE setContextPrinting) - - /*! - * The property holds the date format used by the layout. - * - * The default date format is "TIME_RELATIVE". - * - * \sa dateFormat(), setDateFormat() - */ - Q_PROPERTY(QString dateFormat READ dateFormat WRITE setDateFormat) - - /*! - * The property holds if the thread name is part of the formatted output. - * - * The default value it true for including the thread name. - * - * \sa threadPrinting(), setThreadPrinting() - */ - Q_PROPERTY(bool threadPrinting READ threadPrinting WRITE setThreadPrinting) - - public: - /*! - * The enum DateFormat defines constants for date formats. - * - * \sa setDateFormat(DateFormat), DateTime::toString() - */ - enum DateFormat - { - /*! The none date format string is "NONE". */ - NONE, - /*! - * The iso8601 date format string is "ISO8601". The date will be - * formatted as yyyy-MM-dd hh:mm:ss.zzz. - */ - ISO8601, - /*! - * The absolute date format string is "TIME_ABSOLUTE". The date will be - * formatted as HH:mm:ss.zzz. - */ - TIME_ABSOLUTE, - /*! - * The date date format string is "DATE". The date will be formatted - * as MMM YYYY HH:mm:ss.zzzz. - */ - DATE, - /*! - * The relative date format string is "TIME_RELATIVE". The date will be - * formatted as milliseconds since start of the program. - */ - TIME_RELATIVE - }; - Q_ENUMS(DateFormat) - - TTCCLayout(QObject *pParent = 0); - TTCCLayout(const QString &rDateFormat, - QObject *pParent = 0); - - /*! - * Creates a TTCCLayout with the date formar value specified by - * the \a dateFormat constant and the parent \a pParent. - */ - TTCCLayout(DateFormat dateFormat, - QObject *pParent = 0); - - virtual ~TTCCLayout(); - private: - TTCCLayout(const TTCCLayout &rOther); // Not implemented - TTCCLayout &operator=(const TTCCLayout &rOther); // Not implemented - - public: - bool categoryPrefixing() const; - bool contextPrinting() const; - QString dateFormat() const; - // JAVA: bool ignoresThrowable() const; - bool threadPrinting() const; - void setCategoryPrefixing(bool categoryPrefixing); - void setContextPrinting(bool contextPrinting); - void setDateFormat(const QString &rDateFormat); - - /*! - * Sets the date format to the value specified by the \a dateFormat - * constant. - */ - void setDateFormat(DateFormat dateFormat); - - // JAVA: setIgnoresThrowable(bool ignoresThrowable); - void setThreadPrinting(bool threadPrinting); - virtual QString format(const LoggingEvent &rEvent); - - protected: -#ifndef QT_NO_DEBUG_STREAM - /*! - * Writes all object member variables to the given debug stream - * \a rDebug and returns the stream. - * - * - * %TTCCLayout(name:"TTCC" categoryprefixing:true - * contextprinting:true dateformat:"ISO8601" - * referencecount:1 threadprinting:true) - * - * \sa QDebug, operator<<(QDebug debug, const LogObject &rLogObject) - */ - virtual QDebug debug(QDebug &rDebug) const; -#endif // QT_NO_DEBUG_STREAM - - private: - void updatePatternFormatter(); - - private: - bool mCategoryPrefixing; - bool mContextPrinting; - QString mDateFormat; - bool mThreadPrinting; - PatternFormatter *mpPatternFormatter; - }; - - - /************************************************************************** - * Operators, Helper - **************************************************************************/ - - - /************************************************************************** - * Inline - **************************************************************************/ - - inline bool TTCCLayout::categoryPrefixing() const - { return mCategoryPrefixing; } - - inline bool TTCCLayout::contextPrinting() const - { return mContextPrinting; } - - inline QString TTCCLayout::dateFormat() const - { return mDateFormat; } - - inline bool TTCCLayout::threadPrinting() const - { return mThreadPrinting; } - - inline void TTCCLayout::setCategoryPrefixing(bool categoryPrefixing) - { mCategoryPrefixing = categoryPrefixing; - updatePatternFormatter(); } - - inline void TTCCLayout::setContextPrinting(bool contextPrinting) - { mContextPrinting = contextPrinting; - updatePatternFormatter(); } - - inline void TTCCLayout::setDateFormat(const QString &rDateFormat) - { mDateFormat = rDateFormat; - updatePatternFormatter(); } - - inline void TTCCLayout::setThreadPrinting(bool threadPrinting) - { mThreadPrinting = threadPrinting; - updatePatternFormatter(); } - - -} // namespace Log4Qt - - -// Q_DECLARE_TYPEINFO(Log4Qt::TTCCLayout, Q_COMPLEX_TYPE); // Use default - - -#endif // LOG4QT_TTCCLAYOUT_H diff --git a/src/log4qt/src/log4qt/varia/debugappender.cpp b/src/log4qt/src/log4qt/varia/debugappender.cpp deleted file mode 100644 index d4d0bd2..0000000 --- a/src/log4qt/src/log4qt/varia/debugappender.cpp +++ /dev/null @@ -1,127 +0,0 @@ -/****************************************************************************** - * - * package: Log4Qt - * file: debugappender.cpp - * created: September 2007 - * author: Martin Heinrich - * - * - * Copyright 2007 Martin Heinrich - * - * 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. - * - ******************************************************************************/ - - - -/****************************************************************************** - * Dependencies - ******************************************************************************/ - - -#include "log4qt/varia/debugappender.h" - -#include -#include -#include "log4qt/layout.h" -#include "log4qt/loggingevent.h" -#if defined(Q_WS_WIN) || defined(Q_OS_WIN32) - #include -#endif - -namespace Log4Qt -{ - - - /************************************************************************** - * Declarations - **************************************************************************/ - - - - /************************************************************************** - * C helper functions - **************************************************************************/ - - - - /************************************************************************** - * Class implementation: DebugAppender - **************************************************************************/ - - - DebugAppender::DebugAppender(Layout *pLayout, - QObject *pParent) : - AppenderSkeleton(pParent) - { - setLayout(pLayout); - } - - - bool DebugAppender::requiresLayout() const - { - return true; - } - - - void DebugAppender::append(const LoggingEvent &rEvent) - { - // Q_ASSERT_X(, "DebugAppender::append()", "Lock must be held by caller"); - Q_ASSERT_X(layout(), "DebugAppender::append()", "Layout must not be null"); - - QString message(layout()->format(rEvent)); -#if defined(Q_OS_WIN32) || defined(Q_WS_WIN) - #if (QT_VERSION < 0x050000) - QT_WA({ - OutputDebugStringW(reinterpret_cast(message.utf16())); - }, { - OutputDebugStringA(message.toLocal8Bit().data()); - }); - #else - OutputDebugStringW(reinterpret_cast(message.utf16())); - #endif -#else - fprintf(stderr, "%s", message.toLocal8Bit().data()); - fflush(stderr); -#endif - } - - - - /************************************************************************** - * Implementation: Operators, Helper - **************************************************************************/ - - -#ifndef QT_NO_DEBUG_STREAM - QDebug DebugAppender::debug(QDebug &rDebug) const - { - QString layout_name; - if (layout()) - layout_name = layout()->name(); - - rDebug.nospace() << "DebugAppender(" - << "name:" << name() << " " - << "filter:" << firstFilter() << " " - << "isactive:" << isActive() << " " - << "isclosed:" << isClosed() << " " - << "layout:" << layout_name << " " - << "referencecount:" << referenceCount() << " " - << "threshold:" << threshold().toString() - << ")"; - return rDebug.space(); - } -#endif // QT_NO_DEBUG_STREAM - - -} // namspace Log4Qt diff --git a/src/log4qt/src/log4qt/varia/debugappender.h b/src/log4qt/src/log4qt/varia/debugappender.h deleted file mode 100644 index fc2b7f0..0000000 --- a/src/log4qt/src/log4qt/varia/debugappender.h +++ /dev/null @@ -1,133 +0,0 @@ -/****************************************************************************** - * - * package: Log4Qt - * file: debugappender.h - * created: September 2007 - * author: Martin Heinrich - * - * - * Copyright 2007 Martin Heinrich - * - * 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. - * - ******************************************************************************/ - -#ifndef LOG4QT_DEBUGAPPENDER_H -#define LOG4QT_DEBUGAPPENDER_H - - -/****************************************************************************** - * Dependencies - ******************************************************************************/ - -#include "log4qt/appenderskeleton.h" - - -/****************************************************************************** - * Declarations - ******************************************************************************/ - -namespace Log4Qt -{ - - /*! - * \brief The class DebugAppender appends logging events to the platform - * specific debug output. - * - * A DebugAppender appends to the Debugger on Windows and to stderr on all - * other systems. - * - * \note All the functions declared in this class are thread-safe. - * - * \note The ownership and lifetime of objects of this class are managed. - * See \ref Ownership "Object ownership" for more details. - */ - class DebugAppender : public AppenderSkeleton - { - Q_OBJECT - - public: - /*! - * Creates a DebugAppender. - */ - DebugAppender(QObject *pParent = 0); - - /*! - * Creates a DebugAppender with the specified layout \a pLayout - */ - DebugAppender(Layout *pLayout, - QObject *pParent = 0); - - // virtual ~DebugAppender(); // Use compiler default - private: - DebugAppender(const DebugAppender &rOther); // Not implemented - DebugAppender &operator=(const DebugAppender &rOther); // Not implemented - - public: - /*! - * The DebugAppended requires a layout. The function returns true. - * - * \sa setLayout() - */ - virtual bool requiresLayout() const; - - protected: - /*! - * Appends the specified logging event \a rEvent to the debug output. - * The output is formatted using the appender's layout. - * - * The method is called by the AppenderSkeleton::doAppend() after it - * the entry conditions have been tested and it has been found that the - * logging event needs to be appended. - * - * \sa setLayout(), AppenderSkeleton::doAppend(), checkEntryConditions() - */ - virtual void append(const LoggingEvent &rEvent); - -#ifndef QT_NO_DEBUG_STREAM - /*! - * Writes all object member variables to the given debug stream \a rDebug - * and returns the stream. - * - * - * %DebugAppender(name:"DA" filter:0x3bee6b8 isactive:true isclosed:false - * layout:"SL" referencecount:1 threshold:"NULL") - * - * \sa QDebug, operator<<(QDebug debug, const LogObject &rLogObject) - */ - virtual QDebug debug(QDebug &rDebug) const; -#endif // QT_NO_DEBUG_STREAM - }; - - - /************************************************************************** - * Operators, Helper - **************************************************************************/ - - - /************************************************************************** - * Inline - **************************************************************************/ - - inline DebugAppender::DebugAppender(QObject *pParent) : - AppenderSkeleton(pParent) - {} - - -} // namespace Log4Qt - - -// Q_DECLARE_TYPEINFO(Log4Qt::DebugAppender, Q_COMPLEX_TYPE); // Use default - - -#endif // LOG4QT_DEBUGAPPENDER_H diff --git a/src/log4qt/src/log4qt/varia/denyallfilter.cpp b/src/log4qt/src/log4qt/varia/denyallfilter.cpp deleted file mode 100644 index 31d8f64..0000000 --- a/src/log4qt/src/log4qt/varia/denyallfilter.cpp +++ /dev/null @@ -1,77 +0,0 @@ -/****************************************************************************** - * - * package: Log4Qt - * file: denyallfilter.cpp - * created: September 2007 - * author: Martin Heinrich - * - * - * Copyright 2007 Martin Heinrich - * - * 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. - * - ******************************************************************************/ - - - -/****************************************************************************** - * Dependencies - ******************************************************************************/ - - -#include "log4qt/varia/denyallfilter.h" - -#include - - -namespace Log4Qt -{ - - - /************************************************************************** - * Declarations - **************************************************************************/ - - - - /************************************************************************** - * C helper functions - **************************************************************************/ - - - - /************************************************************************** - * Class implementation: Filter - **************************************************************************/ - - -#ifndef QT_NO_DEBUG_STREAM - QDebug DenyAllFilter::debug(QDebug &rDebug) const - { - rDebug.nospace() << "DenyAllFilter(" - << "next:" << next() - << "referencecount:" << referenceCount() << " " - << ")"; - return rDebug.space(); - } -#endif // QT_NO_DEBUG_STREAM - - - - /************************************************************************** - * Implementation: Operators, Helper - **************************************************************************/ - - - -} // namespace Log4Qt diff --git a/src/log4qt/src/log4qt/varia/denyallfilter.h b/src/log4qt/src/log4qt/varia/denyallfilter.h deleted file mode 100644 index e67ffaa..0000000 --- a/src/log4qt/src/log4qt/varia/denyallfilter.h +++ /dev/null @@ -1,105 +0,0 @@ -/****************************************************************************** - * - * package: Log4Qt - * file: denyallfilter.h - * created: September 2007 - * author: Martin Heinrich - * - * - * changes Feb 2009, Martin Heinrich - * - Fixed a compile error on VS 2008 by using Q_UNUSED(&rEvent) - * instead of Q_UNUSED(rEvent) - * - * - * Copyright 2007 - 2009 Martin Heinrich - * - * 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. - * - ******************************************************************************/ - -#ifndef LOG4QT_DENYALLFILTER_H -#define LOG4QT_DENYALLFILTER_H - - -/****************************************************************************** - * Dependencies - ******************************************************************************/ - -#include "log4qt/spi/filter.h" - - -/****************************************************************************** - * Declarations - ******************************************************************************/ - -namespace Log4Qt -{ - - /*! - * \brief The class DenyAllFilter drops all logging events - * - * \note The ownership and lifetime of objects of this class are managed. - * See \ref Ownership "Object ownership" for more details. - */ - class DenyAllFilter : public Filter - { - Q_OBJECT - - public: - DenyAllFilter(QObject *pParent = 0); - // DenyAllFilter(const DenyAllFilter &rOther); // Use compiler default - // virtual ~DenyAllFilter(); // Use compiler default - // DenyAllFilter &operator=(const DenyAllFilter &rOther); // Use compiler default - - virtual Decision decide(const LoggingEvent &rEvent) const; - - protected: -#ifndef QT_NO_DEBUG_STREAM - /*! - * Writes all object member variables to the given debug stream \a rDebug - * and returns the stream. - * - * - * %DenyAllFilter(next:QObject(0x0) referencecount:1 ) - * - * \sa QDebug, operator<<(QDebug debug, const LogObject &rLogObject) - */ - virtual QDebug debug(QDebug &rDebug) const; -#endif // QT_NO_DEBUG_STREAM - }; - - - /************************************************************************* - * Operators, Helper - *************************************************************************/ - - - /************************************************************************* - * Inline - *************************************************************************/ - - inline DenyAllFilter::DenyAllFilter(QObject *pParent) : - Filter(pParent) - {} - - inline Filter::Decision DenyAllFilter::decide(const LoggingEvent &rEvent) const - { Q_UNUSED(&rEvent); return Filter::DENY; } - - -} // namespace Log4Qt - - -// Q_DECLARE_TYPEINFO(Log4Qt::DenyAllFilter, Q_MOVABLE_TYPE); // Use default - - -#endif // LOG4QT_DENYALLFILTER_H diff --git a/src/log4qt/src/log4qt/varia/levelmatchfilter.cpp b/src/log4qt/src/log4qt/varia/levelmatchfilter.cpp deleted file mode 100644 index 32a3d84..0000000 --- a/src/log4qt/src/log4qt/varia/levelmatchfilter.cpp +++ /dev/null @@ -1,100 +0,0 @@ -/****************************************************************************** - * - * package: Log4Qt - * file: levelmatchfilter.cpp - * created: September 2007 - * author: Martin Heinrich - * - * - * Copyright 2007 Martin Heinrich - * - * 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. - * - ******************************************************************************/ - - - -/****************************************************************************** - * Dependencies - ******************************************************************************/ - - -#include "log4qt/varia/levelmatchfilter.h" - -#include -#include "log4qt/loggingevent.h" - - -namespace Log4Qt -{ - - - /************************************************************************** - * Declarations - **************************************************************************/ - - - - /************************************************************************** - * C helper functions - **************************************************************************/ - - - - /************************************************************************** - * Class implementation: Filter - **************************************************************************/ - - - LevelMatchFilter::LevelMatchFilter(QObject *pParent) : - Filter(pParent), - mAcceptOnMatch(true), - mLevelToMatch(Level::NULL_INT) - {} - - - Filter::Decision LevelMatchFilter::decide(const LoggingEvent &rEvent) const - { - if (mLevelToMatch == Level::NULL_INT || - rEvent.level() != mLevelToMatch) - return Filter::NEUTRAL; - - if (mAcceptOnMatch) - return Filter::ACCEPT; - else - return Filter::DENY; - } - - -#ifndef QT_NO_DEBUG_STREAM - QDebug LevelMatchFilter::debug(QDebug &rDebug) const - { - rDebug.nospace() << "LevelMatchFilter(" - << "acceptonmatch:" << mAcceptOnMatch << " " - << "leveltomatch:" << mLevelToMatch.toString() << " " - << "next:" << next() - << "referencecount:" << referenceCount() << " " - << ")"; - return rDebug.space(); - } -#endif // QT_NO_DEBUG_STREAM - - - - /************************************************************************** - * Implementation: Operators, Helper - **************************************************************************/ - - - -} // namespace Log4Qt diff --git a/src/log4qt/src/log4qt/varia/levelmatchfilter.h b/src/log4qt/src/log4qt/varia/levelmatchfilter.h deleted file mode 100644 index b2fb44c..0000000 --- a/src/log4qt/src/log4qt/varia/levelmatchfilter.h +++ /dev/null @@ -1,137 +0,0 @@ -/****************************************************************************** - * - * package: Log4Qt - * file: levelmatchfilter.h - * created: September 2007 - * author: Martin Heinrich - * - * - * Copyright 2007 Martin Heinrich - * - * 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. - * - ******************************************************************************/ - -#ifndef LOG4QT_LEVELMATCHFILTER_H -#define LOG4QT_LEVELMATCHFILTER_H - - -/****************************************************************************** - * Dependencies - ******************************************************************************/ - -#include "log4qt/spi/filter.h" - -#include "log4qt/level.h" - - -/****************************************************************************** - * Declarations - ******************************************************************************/ - -namespace Log4Qt -{ - - /*! - * \brief The class LevelMatchFilter allows logging events with a specified - * level. - * - * \note The ownership and lifetime of objects of this class are managed. - * See \ref Ownership "Object ownership" for more details. - */ - class LevelMatchFilter : public Filter - { - Q_OBJECT - - /*! - * The property holds if an event is accpeted on a match. - * - * The default is true. - * - * \sa acceptOnMatch(), setAcceptOnMatch() - */ - Q_PROPERTY(bool acceptOnMatch READ acceptOnMatch WRITE setAcceptOnMatch) - - /*! - * The property holds the level to match for this filter. - * - * The default is Level::NULL_INT. - * - * \sa levelToMatch(), setLevelToMatch() - */ - Q_PROPERTY(Level levelToMatch READ levelToMatch WRITE setLevelToMatch) - - public: - LevelMatchFilter(QObject *pParent = 0); - // LevelMatchFilter(const LevelMatchFilter &rOther); // Use compiler default - // virtual ~LevelMatchFilter(); // Use compiler default - // LevelMatchFilter &operator=(const LevelMatchFilter &rOther); // Use compiler default - - bool acceptOnMatch() const; - Level levelToMatch() const; - void setAcceptOnMatch(bool accept); - void setLevelToMatch(Level level); - - virtual Decision decide(const LoggingEvent &rEvent) const; - - protected: -#ifndef QT_NO_DEBUG_STREAM - /*! - * Writes all object member variables to the given debug stream \a rDebug - * and returns the stream. - * - * - * %LevelMatchFilter(acceptonmatch:true leveltomatch:"WARN" - * next:Log4Qt::DenyAllFilter(0x3bce3a8) - * referencecount:1 ) - * - * \sa QDebug, operator<<(QDebug debug, const LogObject &rLogObject) - */ - virtual QDebug debug(QDebug &rDebug) const; -#endif // QT_NO_DEBUG_STREAM - - private: - bool mAcceptOnMatch; - Level mLevelToMatch; - }; - - - /************************************************************************** - * Operators, Helper - **************************************************************************/ - - - /************************************************************************** - * Inline - **************************************************************************/ - - inline bool LevelMatchFilter::acceptOnMatch() const - { return mAcceptOnMatch; } - - inline Level LevelMatchFilter::levelToMatch() const - { return mLevelToMatch; } - - inline void LevelMatchFilter::setAcceptOnMatch(bool accept) - { mAcceptOnMatch = accept; } - - inline void LevelMatchFilter::setLevelToMatch(Level level) - { mLevelToMatch = level; } - - -} // namespace Log4Qt - - -// Q_DECLARE_TYPEINFO(Log4Qt::LevelMatchFilter, Q_MOVABLE_TYPE); // Use default - - -#endif // LOG4QT_LEVELMATCHFILTER_H diff --git a/src/log4qt/src/log4qt/varia/levelrangefilter.cpp b/src/log4qt/src/log4qt/varia/levelrangefilter.cpp deleted file mode 100644 index b219cd9..0000000 --- a/src/log4qt/src/log4qt/varia/levelrangefilter.cpp +++ /dev/null @@ -1,104 +0,0 @@ -/****************************************************************************** - * - * package: Log4Qt - * file: levelrangefilter.cpp - * created: September 2007 - * author: Martin Heinrich - * - * - * Copyright 2007 Martin Heinrich - * - * 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. - * - ******************************************************************************/ - - - -/****************************************************************************** - * Dependencies - ******************************************************************************/ - - -#include "log4qt/varia/levelrangefilter.h" - -#include -#include "log4qt/loggingevent.h" - - -namespace Log4Qt -{ - - -/****************************************************************************** - * Declarations - ******************************************************************************/ - - - -/****************************************************************************** - * C helper functions - ******************************************************************************/ - - - -/****************************************************************************** - * Class implementation: Filter - ******************************************************************************/ - - -LevelRangeFilter::LevelRangeFilter(QObject *pParent) : - Filter(pParent), - mAcceptOnMatch(true), - mLevelMin(Level::NULL_INT), - mLevelMax(Level::OFF_INT) -{} - - -Filter::Decision LevelRangeFilter::decide(const LoggingEvent &rEvent) const -{ - if (rEvent.level() < mLevelMin) - return Filter::DENY; - - if (rEvent.level() > mLevelMax) - return Filter::DENY; - - if (mAcceptOnMatch) - return Filter::ACCEPT; - else - return Filter::NEUTRAL; -} - - -#ifndef QT_NO_DEBUG_STREAM -QDebug LevelRangeFilter::debug(QDebug &rDebug) const -{ - rDebug.nospace() << "LevelRangeFilter(" - << "acceptonmatch:" << mAcceptOnMatch << " " - << "levelmin:" << mLevelMin.toString() << " " - << "levelmax:" << mLevelMax.toString() << " " - << "next:" << next() - << "referencecount:" << referenceCount() << " " - << ")"; - return rDebug.space(); -} -#endif // QT_NO_DEBUG_STREAM - - - -/****************************************************************************** - * Implementation: Operators, Helper - ******************************************************************************/ - - - -} // namespace Log4Qt diff --git a/src/log4qt/src/log4qt/varia/levelrangefilter.h b/src/log4qt/src/log4qt/varia/levelrangefilter.h deleted file mode 100644 index 013e533..0000000 --- a/src/log4qt/src/log4qt/varia/levelrangefilter.h +++ /dev/null @@ -1,153 +0,0 @@ -/****************************************************************************** - * - * package: Log4Qt - * file: levelrangefilter.h - * created: September 2007 - * author: Martin Heinrich - * - * - * Copyright 2007 Martin Heinrich - * - * 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. - * - ******************************************************************************/ - -#ifndef LOG4QT_LEVELRANGEFILTER_H -#define LOG4QT_LEVELRANGEFILTER_H - - -/****************************************************************************** - * Dependencies - ******************************************************************************/ - -#include "log4qt/spi/filter.h" - -#include "log4qt/level.h" - - -/****************************************************************************** - * Declarations - ******************************************************************************/ - -namespace Log4Qt -{ - - /*! - * \brief The class LevelMatchFilter allows logging events with levels in a - * specified range. - * - * \note The ownership and lifetime of objects of this class are managed. - * See \ref Ownership "Object ownership" for more details. - */ - class LevelRangeFilter : public Filter - { - Q_OBJECT - - /*! - * The property holds if an event is accpeted on a match. - * - * The default is true. - * - * \sa acceptOnMatch(), acceptOnMatch() - */ - Q_PROPERTY(bool acceptOnMatch READ acceptOnMatch WRITE setAcceptOnMatch) - - /*! - * The property holds the maximum level of the range for this filter. - * - * The default is Level::OFF_INT. - * - * \sa levelMax(), setLevelMax() - */ - Q_PROPERTY(Level levelMax READ levelMax WRITE setLevelMax) - - /*! - * The property holds the minimum level of the range for this filter. - * - * The default is Level::NULL_INT. - * - * \sa levelMin(), setLevelMin() - */ - Q_PROPERTY(Level levelMin READ levelMin WRITE setLevelMin) - - public: - LevelRangeFilter(QObject *pParent = 0); - // LevelRangeFilter(const LevelRangeFilter &rOther); // Use compiler default - // virtual ~LevelRangeFilter(); // Use compiler default - // LevelRangeFilter &operator=(const LevelRangeFilter &rOther); // Use compiler default - - bool acceptOnMatch() const; - Level levelMax() const; - Level levelMin() const; - void setAcceptOnMatch(bool accept); - void setLevelMax(Level level); - void setLevelMin(Level level); - - virtual Decision decide(const LoggingEvent &rEvent) const; - - protected: - /*! - * Writes all object member variables to the given debug stream \a rDebug - * and returns the stream. - * - * - * %LevelRangeFilter(acceptonmatch:true levelmin:"ERROR" levelmax:"FATAL" - * next:Log4Qt::LevelMatchFilter(0x3bcd960) - * referencecount:1 ) - * - * \sa QDebug, operator<<(QDebug debug, const LogObject &rLogObject) - */ - virtual QDebug debug(QDebug &rDebug) const; - - private: - bool mAcceptOnMatch; - Level mLevelMin; - Level mLevelMax; - }; - - - /************************************************************************** - * Operators, Helper - **************************************************************************/ - - - /************************************************************************** - * Inline - **************************************************************************/ - - inline bool LevelRangeFilter::acceptOnMatch() const - { return mAcceptOnMatch; } - - inline Level LevelRangeFilter::levelMax() const - { return mLevelMax; } - - inline Level LevelRangeFilter::levelMin() const - { return mLevelMin; } - - inline void LevelRangeFilter::setAcceptOnMatch(bool accept) - { mAcceptOnMatch = accept; } - - inline void LevelRangeFilter::setLevelMax(Level level) - { mLevelMax = level; } - - inline void LevelRangeFilter::setLevelMin(Level level) - { mLevelMin = level; } - - -} // namespace Log4Qt - - -// Q_DECLARE_TYPEINFO(Log4Qt::LevelRangeFilter, Q_MOVABLE_TYPE); // Use default - - -#endif // LOG4QT_LEVELRANGEFILTER_H diff --git a/src/log4qt/src/log4qt/varia/listappender.cpp b/src/log4qt/src/log4qt/varia/listappender.cpp deleted file mode 100644 index db20284..0000000 --- a/src/log4qt/src/log4qt/varia/listappender.cpp +++ /dev/null @@ -1,153 +0,0 @@ -/****************************************************************************** - * - * package: Log4Qt - * file: listappender.cpp - * created: September 2007 - * author: Martin Heinrich - * - * - * Copyright 2007 Martin Heinrich - * - * 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. - * - ******************************************************************************/ - - - -/****************************************************************************** - * Dependencies - ******************************************************************************/ - - -#include "log4qt/varia/listappender.h" - -#include - - - -namespace Log4Qt -{ - - - /************************************************************************** - * Declarations - **************************************************************************/ - - - - /************************************************************************** - * C helper functions - **************************************************************************/ - - - - /************************************************************************** - * Class implementation: ListAppender - **************************************************************************/ - - - ListAppender::ListAppender(QObject *pParent) : - AppenderSkeleton(pParent), - mConfiguratorList(false), - mList(), - mMaxCount(0) - { - } - - - ListAppender::~ListAppender() - { - } - - - QList ListAppender::list() const - { - QMutexLocker locker(&mObjectGuard); - - return mList; - } - - - void ListAppender::setMaxCount(int n) - { - QMutexLocker locker(&mObjectGuard); - - if (n < 0) - { - logger()->warn("Attempt to set maximum count for appender '%1' to %2. Using zero instead", name(), n); - n = 0; - } - mMaxCount = n; - ensureMaxCount(); - } - - - QList ListAppender::clearList() - { - QMutexLocker locker(&mObjectGuard); - - QList result = mList; - mList.clear(); - return result; - } - - - // bool ListAppender::requiresLayout() const; - - - void ListAppender::append(const LoggingEvent &rEvent) - { - // Q_ASSERT_X(, "ListAppender::append()", "Lock must be held by caller") - - if ((mMaxCount <= 0) || (mList.size() < mMaxCount)) - mList << rEvent; - } - - -#ifndef QT_NO_DEBUG_STREAM - QDebug ListAppender::debug(QDebug &rDebug) const - { - rDebug.nospace() << "ListAppender(" - << "name:" << name() << " " - << "count:" << list().count() << " " - << "filter:" << firstFilter() << " " - << "isactive:" << isActive() << " " - << "isclosed:" << isClosed() << " " - << "maxcount:" << maxCount() << " " - << "referencecount:" << referenceCount() << " " - << "threshold:" << threshold().toString() - << ")"; - return rDebug.space(); - } -#endif // QT_NO_DEBUG_STREAM - - - void ListAppender::ensureMaxCount() - { - // Q_ASSERT_X(, "ListAppender::ensureMaxCount()", "Lock must be held by caller") - - if (mMaxCount <= 0) - return; - - while (mList.size() > mMaxCount) - mList.removeFirst(); - } - - - - /************************************************************************** - * Implementation: Operators, Helper - **************************************************************************/ - - -} // namespace Log4Qt diff --git a/src/log4qt/src/log4qt/varia/listappender.h b/src/log4qt/src/log4qt/varia/listappender.h deleted file mode 100644 index 0b35c51..0000000 --- a/src/log4qt/src/log4qt/varia/listappender.h +++ /dev/null @@ -1,174 +0,0 @@ -/****************************************************************************** - * - * package: Log4Qt - * file: listappender.h - * created: September 2007 - * author: Martin Heinrich - * - * - * Copyright 2007 Martin Heinrich - * - * 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. - * - ******************************************************************************/ - -#ifndef LOG4QT_LISTAPPENDER_H -#define LOG4QT_LISTAPPENDER_H - - -/****************************************************************************** - * Dependencies - ******************************************************************************/ - -#include "log4qt/appenderskeleton.h" - -#include -#include -#include "log4qt/loggingevent.h" - - -/****************************************************************************** - * Declarations - ******************************************************************************/ - -namespace Log4Qt -{ - - /*! - * \brief The class ListAppender appends logging events to a list for later - * processing. - * - * \note All the functions declared in this class are thread-safe. - * - * \note The ownership and lifetime of objects of this class are managed. - * See \ref Ownership "Object ownership" for more details. - */ - class ListAppender : public AppenderSkeleton - { - Q_OBJECT - - /*! - * The property holds, if the Appender is used by a configurator. - * - * The default value is false for not being a configurator list. - * - * \sa configuratorList(), setConfiguratorList() - */ - Q_PROPERTY(bool configuratorList READ configuratorList WRITE setConfiguratorList) - - /*! - * The property holds the maximum count used by the appender. - * - * The default maximum count is -1 for unlimited. - * - * \sa maxCount(), setMaxCount() - */ - Q_PROPERTY(int maxCount READ maxCount WRITE setMaxCount) - - public: - ListAppender(QObject *pParent = 0); - virtual ~ListAppender(); - private: - ListAppender(const ListAppender &rOther); // Not implemented - ListAppender &operator=(const ListAppender &rOther); // Not implemented - - public: - /*! - * Returns true, if the appender is used by a configurator. Otherweise it returns - * false. - * - * \sa setConfiguratorList() - */ - bool configuratorList() const; - - QList list() const; - int maxCount() const; - - /*! - * Sets that the appender is used by a configurator. If set to true, the appender - * will not be removed from a Logger when Logger::removeAllAppenders()is called. - * This way the appender can collect events raised during the configuration process. - * - * \sa configuratorList(), BasicConfigurator, PropertyConfigurator, - * ConfiguratorHelper::configureError() - */ - void setConfiguratorList(bool isConfiguratorList); - - void setMaxCount(int n); - - QList clearList(); - virtual bool requiresLayout() const; - - protected: - virtual void append(const LoggingEvent &rEvent); - -#ifndef QT_NO_DEBUG_STREAM - /*! - * Writes all object member variables to the given debug stream - * \a rDebug and returns the stream. - * - * - * %ListAppender(name:"LA" count:1 filter:0x41fa488 isactive:true - * isclosed:false maxcount:170 referencecount:1 - * threshold:"TRACE_SET") - * - * \sa QDebug, operator<<(QDebug debug, const LogObject &rLogObject) - */ - virtual QDebug debug(QDebug &rDebug) const; -#endif // QT_NO_DEBUG_STREAM - - /*! - * Ensures that the count of events is less or equal then the maxium - * count. If the list contains too many items, items are deleted from - * the begin of the list. - */ - void ensureMaxCount(); - - private: - volatile bool mConfiguratorList; - QList mList; - volatile int mMaxCount; - }; - - - /************************************************************************** - * Operators, Helper - **************************************************************************/ - - - /************************************************************************** - * Inline - **************************************************************************/ - - inline bool ListAppender::configuratorList() const - { // QMutexLocker locker(&mObjectGuard); // Read/Write of int is safe - return mConfiguratorList; } - - inline int ListAppender::maxCount() const - { return mMaxCount; } - - inline void ListAppender::setConfiguratorList(bool isConfiguratorList) - { // QMutexLocker locker(&mObjectGuard); // Read/Write of int is safe - mConfiguratorList = isConfiguratorList; } - - inline bool ListAppender::requiresLayout() const - { return false; } - - -} // namespace Log4Qt - - -// Q_DECLARE_TYPEINFO(Log4Qt::ListAppender, Q_COMPLEX_TYPE); // Use default - - -#endif // LOG4QT_LISTAPPENDER_H diff --git a/src/log4qt/src/log4qt/varia/nullappender.cpp b/src/log4qt/src/log4qt/varia/nullappender.cpp deleted file mode 100644 index a12ebf2..0000000 --- a/src/log4qt/src/log4qt/varia/nullappender.cpp +++ /dev/null @@ -1,104 +0,0 @@ -/****************************************************************************** - * - * package: Log4Qt - * file: nullappender.cpp - * created: September 2007 - * author: Martin Heinrich - * - * - * Copyright 2007 Martin Heinrich - * - * 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. - * - ******************************************************************************/ - - - -/****************************************************************************** - * Dependencies - ******************************************************************************/ - - -#include "log4qt/varia/nullappender.h" - -#include -#include "log4qt/layout.h" -#include "log4qt/loggingevent.h" - - - -namespace Log4Qt -{ - - - /************************************************************************** - * Declarations - **************************************************************************/ - - - - /************************************************************************** - * C helper functions - **************************************************************************/ - - - - /************************************************************************** - * Class implementation: NullAppender - **************************************************************************/ - - - NullAppender::NullAppender(QObject *pParent) : - AppenderSkeleton(false, pParent) - { - } - - - NullAppender::~NullAppender() - { - close(); - } - - - void NullAppender::append(const LoggingEvent &rEvent) - { - Q_UNUSED(rEvent); - } - - -#ifndef QT_NO_DEBUG_STREAM - QDebug NullAppender::debug(QDebug &rDebug) const - { - QString layout_name; - if (layout()) - layout_name = layout()->name(); - - rDebug.nospace() << "NullAppender(" - << "name:" << name() << " " - << "isactive:" << isActive() << " " - << "isclosed:" << isClosed() << " " - << "layout:" << layout_name << " " - << "threshold:" << threshold().toString() << " " - << ")"; - return rDebug.space(); - } -#endif // QT_NO_DEBUG_STREAM - - - - /************************************************************************** - * Implementation: Operators, Helper - **************************************************************************/ - - -} // namespace Log4Qt diff --git a/src/log4qt/src/log4qt/varia/nullappender.h b/src/log4qt/src/log4qt/varia/nullappender.h deleted file mode 100644 index becafb9..0000000 --- a/src/log4qt/src/log4qt/varia/nullappender.h +++ /dev/null @@ -1,102 +0,0 @@ -/****************************************************************************** - * - * package: Log4Qt - * file: nullappender.h - * created: September 2007 - * author: Martin Heinrich - * - * - * Copyright 2007 Martin Heinrich - * - * 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. - * - ******************************************************************************/ - -#ifndef LOG4QT_NULLAPPENDER_H -#define LOG4QT_NULLAPPENDER_H - - -/****************************************************************************** - * Dependencies - ******************************************************************************/ - -#include "log4qt/appenderskeleton.h" - - -/****************************************************************************** - * Declarations - ******************************************************************************/ - -namespace Log4Qt -{ - -/*! - * \brief The class NullAppender ignores all requests to append. - * - * \note All the functions declared in this class are thread-safe. - * - * \note The ownership and lifetime of objects of this class are managed. See - * \ref Ownership "Object ownership" for more details. - */ -class NullAppender : public AppenderSkeleton -{ - Q_OBJECT - -public: - NullAppender(QObject *pParent = 0); - virtual ~NullAppender(); -private: - NullAppender(const NullAppender &rOther); // Not implemented - NullAppender &operator=(const NullAppender &rOther); // Not implemented - -public: - virtual bool requiresLayout() const; - -protected: - virtual void append(const LoggingEvent &rEvent); - -#ifndef QT_NO_DEBUG_STREAM - /*! - * Writes all object member variables to the given debug stream \a rDebug and - * returns the stream. - * - * - * %NullAppender() - * - * \sa QDebug, operator<<(QDebug debug, const LogObject &rLogObject) - */ - virtual QDebug debug(QDebug &rDebug) const; -#endif // QT_NO_DEBUG_STREAM -}; - - -/****************************************************************************** - * Operators, Helper - ******************************************************************************/ - - -/****************************************************************************** - * Inline - ******************************************************************************/ - -inline bool NullAppender::requiresLayout() const -{ return false; } - - -} // namespace Log4Qt - - -// Q_DECLARE_TYPEINFO(Log4Qt::NullAppender, Q_COMPLEX_TYPE); // Use default - - -#endif // LOG4QT_NULLAPPENDER_H diff --git a/src/log4qt/src/log4qt/varia/stringmatchfilter.cpp b/src/log4qt/src/log4qt/varia/stringmatchfilter.cpp deleted file mode 100644 index e660b21..0000000 --- a/src/log4qt/src/log4qt/varia/stringmatchfilter.cpp +++ /dev/null @@ -1,101 +0,0 @@ -/****************************************************************************** - * - * package: Log4Qt - * file: stringmatchfilter.cpp - * created: September 2007 - * author: Martin Heinrich - * - * - * Copyright 2007 Martin Heinrich - * - * 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. - * - ******************************************************************************/ - - - -/****************************************************************************** - * Dependencies - ******************************************************************************/ - - -#include "log4qt/varia/stringmatchfilter.h" - -#include -#include "log4qt/loggingevent.h" - - -namespace Log4Qt -{ - - - /************************************************************************** - * Declarations - **************************************************************************/ - - - - /************************************************************************** - * C helper functions - **************************************************************************/ - - - - /************************************************************************** - * Class implementation: Filter - **************************************************************************/ - - - StringMatchFilter::StringMatchFilter(QObject *pParent) : - Filter(pParent), - mAcceptOnMatch(true), - mStringToMatch() - {} - - - Filter::Decision StringMatchFilter::decide(const LoggingEvent &rEvent) const - { - if (rEvent.message().isEmpty() || - mStringToMatch.isEmpty() || - rEvent.message().indexOf(mStringToMatch) < 0) - return Filter::NEUTRAL; - - if (mAcceptOnMatch) - return Filter::ACCEPT; - else - return Filter::DENY; - } - - -#ifndef QT_NO_DEBUG_STREAM - QDebug StringMatchFilter::debug(QDebug &rDebug) const - { - rDebug.nospace() << "StringMatchFilter(" - << "acceptonmatch:" << mAcceptOnMatch << " " - << "referencecount:" << referenceCount() << " " - << "stringtomatch:" << mStringToMatch << " " - << "next:" << next() - << ")"; - return rDebug.space(); - } -#endif // QT_NO_DEBUG_STREAM - - - - /************************************************************************** - * Implementation: Operators, Helper - **************************************************************************/ - - - -} // namespace Log4Qt diff --git a/src/log4qt/src/log4qt/varia/stringmatchfilter.h b/src/log4qt/src/log4qt/varia/stringmatchfilter.h deleted file mode 100644 index 921460f..0000000 --- a/src/log4qt/src/log4qt/varia/stringmatchfilter.h +++ /dev/null @@ -1,133 +0,0 @@ -/****************************************************************************** - * - * package: Log4Qt - * file: stringmatchfilter.h - * created: September 2007 - * author: Martin Heinrich - * - * - * Copyright 2007 Martin Heinrich - * - * 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. - * - ******************************************************************************/ - -#ifndef LOG4QT_STRINGMATCHFILTER_H -#define LOG4QT_STRINGMATCHFILTER_H - - -/****************************************************************************** - * Dependencies - ******************************************************************************/ - -#include "log4qt/spi/filter.h" - - -/****************************************************************************** - * Declarations - ******************************************************************************/ - -namespace Log4Qt -{ - - /*! - * \brief The class StringMatchFilter allows logging events with a - * specified level. - * - * \note The ownership and lifetime of objects of this class are managed. - * See \ref Ownership "Object ownership" for more details. - */ - class StringMatchFilter : public Filter - { - Q_OBJECT - - /*! - * The property holds if an event is accpeted on a match. - * - * The default is true. - * - * \sa acceptOnMatch(), acceptOnMatch() - */ - Q_PROPERTY(bool acceptOnMatch READ acceptOnMatch WRITE setAcceptOnMatch) - - /*! - * The property holds the string to match for this filter. - * - * \sa stringToMatch(), setStringToMatch() - */ - Q_PROPERTY(QString stringToMatch READ stringToMatch WRITE setStringToMatch) - - public: - StringMatchFilter(QObject *pParent = 0); - // StringMatchFilter(const StringMatchFilter &rOther); // Use compiler default - // virtual ~StringMatchFilter(); // Use compiler default - // StringMatchFilter &operator=(const StringMatchFilter &rOther); // Use compiler default - - bool acceptOnMatch() const; - QString stringToMatch() const; - void setAcceptOnMatch(bool accept); - void setStringToMatch(const QString &rString); - - virtual Decision decide(const LoggingEvent &rEvent) const; - - protected: -#ifndef QT_NO_DEBUG_STREAM - /*! - * Writes all object member variables to the given debug stream - * \a rDebug and returns the stream. - * - * - * %StringMatchFilter(acceptonmatch:true referencecount:1 - * stringtomatch:"LDAP_STRONG_AUTH_REQUIRED" - * next:Log4Qt::LevelMatchFilter(0x3bdd960) ) - * - * \sa QDebug, operator<<(QDebug debug, const LogObject &rLogObject) - */ - virtual QDebug debug(QDebug &rDebug) const; -#endif // QT_NO_DEBUG_STREAM - - private: - bool mAcceptOnMatch; - QString mStringToMatch; - }; - - - /************************************************************************** - * Operators, Helper - **************************************************************************/ - - - /************************************************************************** - * Inline - **************************************************************************/ - - inline bool StringMatchFilter::acceptOnMatch() const - { return mAcceptOnMatch; } - - inline QString StringMatchFilter::stringToMatch() const - { return mStringToMatch; } - - inline void StringMatchFilter::setAcceptOnMatch(bool accept) - { mAcceptOnMatch = accept; } - - inline void StringMatchFilter::setStringToMatch(const QString &rString) - { mStringToMatch = rString; } - - -} // namespace Log4Qt - - -// Q_DECLARE_TYPEINFO(Log4Qt::StringMatchFilter, Q_MOVABLE_TYPE); // Use default - - -#endif // LOG4QT_STRINGMATCHFILTER_H diff --git a/src/log4qt/src/log4qt/writerappender.cpp b/src/log4qt/src/log4qt/writerappender.cpp deleted file mode 100644 index 25a633e..0000000 --- a/src/log4qt/src/log4qt/writerappender.cpp +++ /dev/null @@ -1,288 +0,0 @@ -/****************************************************************************** - * - * package: Log4Qt - * file: writerappender.cpp - * created: September 2007 - * author: Martin Heinrich - * - * - * Copyright 2007 Martin Heinrich - * - * 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. - * - ******************************************************************************/ - - - -/****************************************************************************** - * Dependencies - ******************************************************************************/ - - -#include "log4qt/writerappender.h" - -#include -#include -#include "log4qt/layout.h" -#include "log4qt/loggingevent.h" - - - -namespace Log4Qt -{ - - - /************************************************************************** - * Declarations - **************************************************************************/ - - - - /************************************************************************** - * C helper functions - **************************************************************************/ - - - - /************************************************************************** - * Class implementation: WriterAppender - **************************************************************************/ - - - WriterAppender::WriterAppender(QObject *pParent) : - AppenderSkeleton(false, pParent), - mpEncoding(0), - mpWriter(0), - mImmediateFlush(true) - { - } - - - WriterAppender::WriterAppender(Layout *pLayout, - QObject *pParent) : - AppenderSkeleton(false, pParent), - mpEncoding(0), - mpWriter(0), - mImmediateFlush(true) - { - setLayout(pLayout); - } - - - WriterAppender::WriterAppender(Layout *pLayout, - QTextStream *pTextStream, - QObject *pParent) : - AppenderSkeleton(false, pParent), - mpEncoding(0), - mpWriter(pTextStream), - mImmediateFlush(true) - { - setLayout(pLayout); - } - - - WriterAppender::~WriterAppender() - { - close(); - } - - - void WriterAppender::setEncoding(QTextCodec *pEncoding) - { - QMutexLocker locker(&mObjectGuard); - - if (mpEncoding == pEncoding) - return; - - mpEncoding = pEncoding; - if (mpWriter) - { - if (mpEncoding) - mpWriter->setCodec(mpEncoding); - else - mpWriter->setCodec(QTextCodec::codecForLocale()); - } - } - - - void WriterAppender::setWriter(QTextStream *pTextStream) - { - QMutexLocker locker(&mObjectGuard); - - closeWriter(); - - mpWriter = pTextStream; - if (mpEncoding && mpWriter) - mpWriter->setCodec(mpEncoding); - writeHeader(); - } - - - void WriterAppender::activateOptions() - { - QMutexLocker locker(&mObjectGuard); - - if (!writer()) - { - LogError e = LOG4QT_QCLASS_ERROR(QT_TR_NOOP("Activation of Appender '%1' that requires writer and has no writer set"), - APPENDER_ACTIVATE_MISSING_WRITER_ERROR); - e << name(); - logger()->error(e); - return; - } - - AppenderSkeleton::activateOptions(); - } - - - void WriterAppender::close() - { - QMutexLocker locker(&mObjectGuard); - - if (isClosed()) - return; - - AppenderSkeleton::close(); - closeWriter(); - } - - - bool WriterAppender::requiresLayout() const - { - return true; - } - - - void WriterAppender::append(const LoggingEvent &rEvent) - { - // Q_ASSERT_X(, "WriterAppender::append()", "Lock must be held by caller"); - Q_ASSERT_X(layout(), "WriterAppender::append()", "Layout must not be null"); - - QString message(layout()->format(rEvent)); - - *mpWriter << message; - if (handleIoErrors()) - return; - - if (immediateFlush()) - { - mpWriter->flush(); - if (handleIoErrors()) - return; - } - } - - - bool WriterAppender::checkEntryConditions() const - { - // Q_ASSERT_X(, "WriterAppender::checkEntryConditions()", "Lock must be held by caller") - - if (!writer()) - { - LogError e = LOG4QT_QCLASS_ERROR(QT_TR_NOOP("Use of appender '%1' without a writer set"), - APPENDER_USE_MISSING_WRITER_ERROR); - e << name(); - logger()->error(e); - return false; - } - - return AppenderSkeleton::checkEntryConditions(); - } - - - void WriterAppender::closeWriter() - { - // Q_ASSERT_X(, "WriterAppender::closeWriter()", "Lock must be held by caller") - - if (!mpWriter) - return; - - writeFooter(); - mpWriter = 0; - } - - -#ifndef QT_NO_DEBUG_STREAM - QDebug WriterAppender::debug(QDebug &rDebug) const - { - QString layout_name; - if (layout()) - layout_name = layout()->name(); - QString codec_name; - if (encoding()) - codec_name = QLatin1String(encoding()->name()); - - rDebug.nospace() << "WriterAppender(" - << "name:" << name() << " " - << "encoding:" << codec_name << " " - << "filter:" << firstFilter() - << "immediateFlush:" << immediateFlush() - << "isactive:" << isActive() - << "isclosed:" << isClosed() - << "layout:" << layout_name - << "referencecount:" << referenceCount() << " " - << "threshold:" << threshold().toString() - << "writer:" << writer() - << ")"; - return rDebug.space(); - } -#endif // QT_NO_DEBUG_STREAM - - - bool WriterAppender::handleIoErrors() const - { - return false; - } - - - void WriterAppender::writeFooter() const - { - // Q_ASSERT_X(, "WriterAppender::writeFooter()", "Lock must be held by caller") - - if (!layout() || !mpWriter) - return; - - QString footer = layout()->footer(); - if (footer.isEmpty()) - return; - - *mpWriter << footer << Layout::endOfLine(); - if (handleIoErrors()) - return; - } - - - void WriterAppender::writeHeader() const - { - // Q_ASSERT_X(, "WriterAppender::writeHeader()", "Lock must be held by caller") - - if (!layout() || !mpWriter) - return; - - QString header = layout()->header(); - if (header.isEmpty()) - return; - - *mpWriter << header << Layout::endOfLine(); - if (handleIoErrors()) - return; - } - - - - /****************************************************************************** - * Implementation: Operators, Helper - ******************************************************************************/ - - -} // namespace Log4Qt diff --git a/src/log4qt/src/log4qt/writerappender.h b/src/log4qt/src/log4qt/writerappender.h deleted file mode 100644 index 5c8da09..0000000 --- a/src/log4qt/src/log4qt/writerappender.h +++ /dev/null @@ -1,200 +0,0 @@ -/****************************************************************************** - * - * package: Log4Qt - * file: writerappender.h - * created: September 2007 - * author: Martin Heinrich - * - * - * Copyright 2007 Martin Heinrich - * - * 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. - * - ******************************************************************************/ - -#ifndef LOG4QT_WRITERAPPENDER_H -#define LOG4QT_WRITERAPPENDER_H - - -/****************************************************************************** - * Dependencies - ******************************************************************************/ - -#include "log4qt/appenderskeleton.h" - - -/****************************************************************************** - * Declarations - ******************************************************************************/ - -class QTextCodec; -class QTextStream; - -namespace Log4Qt -{ - - /*! - * \brief The class WriterAppender appends log events to a QTextStream. - * - * \note All the functions declared in this class are thread-safe. - *   - * \note The ownership and lifetime of objects of this class are managed. - * See \ref Ownership "Object ownership" for more details. - */ - class WriterAppender : public AppenderSkeleton - { - Q_OBJECT - - /*! - * The property holds the codec the appender uses. - * - * The default is null to use the codec the writer has set. - * - * \sa encoding(), setEncoding() - */ - Q_PROPERTY(QTextCodec* encoding READ encoding WRITE setEncoding) - - /*! - * The property holds the writer the appender uses. - * - * \sa writer(), setWriter() - */ - Q_PROPERTY(QTextStream* writer READ writer WRITE setWriter) - - /*! - * The property holds, if the writer flushes after all write operations. - * - * The default is true for flushing. - * - * \sa immediateFlush(), setImmediateFlush() - */ - Q_PROPERTY(bool immediateFlush READ immediateFlush WRITE setImmediateFlush) - - public: - WriterAppender(QObject *pParent = 0); - WriterAppender(Layout *pLayout, - QObject *pParent = 0); - WriterAppender(Layout *pLayout, - QTextStream *pTextStream, - QObject *pParent = 0); - virtual ~WriterAppender(); - private: - WriterAppender(const WriterAppender &rOther); // Not implemented - WriterAppender &operator=(const WriterAppender &rOther); // Not implemented - - public: - virtual bool requiresLayout() const; - QTextCodec *encoding() const; - bool immediateFlush() const; - QTextStream *writer() const; - - /*! - * Sets the codec used by the writer to \a pTextCoded. - * - * If a codec is set with setEncoding, it will overwrite the codec set - * in the text stream. A subsequent call with \a pTextCoded equals null - * will resets the codec to the default QTextCodec::codecForLocale(). - * - * \sa encoding(), QTextSream::setCodec(), QTextCodec::codecForLocale() - */ - void setEncoding(QTextCodec *pTextCodec); - void setImmediateFlush(bool immediateFlush); - void setWriter(QTextStream *pTextStream); - - virtual void activateOptions(); - virtual void close(); - - protected: - virtual void append(const LoggingEvent &rEvent); - - /*! - * Tests if all entry conditions for using append() in this class are - * met. - * - * If a conditions is not met, an error is logged and the function - * returns false. Otherwise the result of - * AppenderSkeleton::checkEntryConditions() is returned. - * - * The checked conditions are: - * - A writer has been set (APPENDER_USE_MISSING_WRITER_ERROR) - * - * The function is called as part of the checkEntryConditions() chain - * started by AppenderSkeleton::doAppend(). - * - * \sa AppenderSkeleton::doAppend(), - * AppenderSkeleton::checkEntryConditions() - */ - virtual bool checkEntryConditions() const; - - void closeWriter(); - -#ifndef QT_NO_DEBUG_STREAM - /*! - * Writes all object member variables to the given debug stream - * \a rDebug and returns the stream. - * - * - * %WriterAppender(name:"WA" encoding:"" immediateFlush:true - * isactive:false isclosed:false layout:"TTCC" - * referencecount:1 threshold:"NULL" - * writer:0x0) - * - * \sa QDebug, operator<<(QDebug debug, const LogObject &rLogObject ) - */ - virtual QDebug debug(QDebug &rDebug) const; -#endif // QT_NO_DEBUG_STREAM - - virtual bool handleIoErrors() const; - void writeFooter() const; - void writeHeader() const; - - private: - QTextCodec *mpEncoding; - QTextStream *mpWriter; - volatile bool mImmediateFlush; - }; - - - /************************************************************************** - * Operators, Helper - **************************************************************************/ - - - /************************************************************************** - * Inline - **************************************************************************/ - - inline QTextCodec *WriterAppender::encoding() const - { QMutexLocker locker(&mObjectGuard); - return mpEncoding; } - - inline bool WriterAppender::immediateFlush() const - { // QMutexLocker locker(&mObjectGuard); // Read/Write of int is safe - return mImmediateFlush; } - - inline QTextStream *WriterAppender::writer() const - { // QMutexLocker locker(&mObjectGuard); // Read/Write of int is safe - return mpWriter; } - - inline void WriterAppender::setImmediateFlush(bool immediateFlush) - { // QMutexLocker locker(&mObjectGuard); // Read/Write of int is safe - mImmediateFlush = immediateFlush; } - - -} // namespace Log4Qt - - -// Q_DECLARE_TYPEINFO(Log4Qt::WriterAppender, Q_COMPLEX_TYPE); // Use default - - -#endif // LOG4QT_WRITERAPPENDER_H From c7c7e3c1604da275a599f3738cc08bd21b0a082f Mon Sep 17 00:00:00 2001 From: winnerym100 Date: Sat, 17 Apr 2021 17:18:05 +0800 Subject: [PATCH 05/35] =?UTF-8?q?feature=EF=BC=9A=E6=97=A5=E5=BF=97?= =?UTF-8?q?=E5=BC=82=E6=AD=A5=E8=BE=93=E5=87=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- debian/changelog | 6 ++ src/log4qt/log4qt/appenderskeleton.h | 4 ++ .../log4qt/dailyrollingfileappender.cpp | 14 +++- src/log4qt/log4qt/dailyrollingfileappender.h | 1 + src/log4qt/log4qt/helpers/asyncdispatcher.cpp | 48 +++++++++++++ src/log4qt/log4qt/helpers/asyncdispatcher.h | 55 +++++++++++++++ src/log4qt/log4qt/log4qt.pri | 2 + src/log4qt/log4qt/loggingevent.cpp | 6 +- src/log4qt/log4qt/loggingevent.h | 4 +- src/log4qt/log4qt/rollingfileappender.cpp | 11 +++ src/log4qt/log4qt/rollingfileappender.h | 1 + src/log4qt/log4qt/varia/debugappender.cpp | 22 ++++++ src/log4qt/log4qt/varia/debugappender.h | 1 + src/log4qt/log4qt/varia/listappender.cpp | 8 +++ src/log4qt/log4qt/varia/listappender.h | 1 + src/log4qt/log4qt/varia/nullappender.cpp | 5 ++ src/log4qt/log4qt/varia/nullappender.h | 1 + src/log4qt/log4qt/writerappender.cpp | 68 +++++++++++++++++-- src/log4qt/log4qt/writerappender.h | 8 ++- src/log4qt/ukui-log4qt.pro | 2 +- 20 files changed, 257 insertions(+), 11 deletions(-) create mode 100644 src/log4qt/log4qt/helpers/asyncdispatcher.cpp create mode 100644 src/log4qt/log4qt/helpers/asyncdispatcher.h diff --git a/debian/changelog b/debian/changelog index d6d6069..19948c1 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,9 @@ +ukui-interface (1.0.1-3) v101; urgency=medium + + * feature: 日志异步输出 + + -- Yang Min Sat, 17 Apr 2021 16:59:43 +0800 + ukui-interface (1.0.1-2) v101; urgency=medium * 修复bug:修复隔天重新打开程序时日志文件未按日期分割 diff --git a/src/log4qt/log4qt/appenderskeleton.h b/src/log4qt/log4qt/appenderskeleton.h index 4101e1d..8438ac1 100644 --- a/src/log4qt/log4qt/appenderskeleton.h +++ b/src/log4qt/log4qt/appenderskeleton.h @@ -124,6 +124,7 @@ namespace Log4Qt protected: virtual void append(const LoggingEvent &rEvent) = 0; + virtual void asyncAppend(const LoggingEvent &rEvent) = 0; /*! * Tests if all entry conditions for using append() in this class are @@ -159,6 +160,9 @@ namespace Log4Qt Level mThreshold; LogObjectPtr mpHeadFilter; LogObjectPtr mpTailFilter; + + // need AsyncDispatcher to call asyncAppend method + friend class AsyncDispatcher; }; diff --git a/src/log4qt/log4qt/dailyrollingfileappender.cpp b/src/log4qt/log4qt/dailyrollingfileappender.cpp index fdedb33..19f50e2 100644 --- a/src/log4qt/log4qt/dailyrollingfileappender.cpp +++ b/src/log4qt/log4qt/dailyrollingfileappender.cpp @@ -124,7 +124,7 @@ namespace Log4Qt computeFrequency(); if (!mActiveDatePattern.isEmpty()) { - #if 1 + #ifdef UKUILOG4QT_EXTRA_ENABLE QFileInfo fileInfo(file()); if (!fileInfo.exists()) { computeRollOverTime(); @@ -142,11 +142,21 @@ namespace Log4Qt void DailyRollingFileAppender::append(const LoggingEvent &rEvent) { // Q_ASSERT_X(, "DailyRollingFileAppender::append()", "Lock must be held by caller") - + #ifndef UKUILOG4QT_EXTRA_ENABLE if (QDateTime::currentDateTime() > mRollOverTime) rollOver(); + #endif FileAppender::append(rEvent); } + + void DailyRollingFileAppender::asyncAppend(const LoggingEvent &rEvent) + { + // Q_ASSERT_X(, "DailyRollingFileAppender::asyncAppend()", "Lock must be held by caller") + + if (QDateTime::currentDateTime() > mRollOverTime) + rollOver(); + FileAppender::asyncAppend(rEvent); + } bool DailyRollingFileAppender::checkEntryConditions() const diff --git a/src/log4qt/log4qt/dailyrollingfileappender.h b/src/log4qt/log4qt/dailyrollingfileappender.h index ee72eb9..3228c4f 100644 --- a/src/log4qt/log4qt/dailyrollingfileappender.h +++ b/src/log4qt/log4qt/dailyrollingfileappender.h @@ -113,6 +113,7 @@ namespace Log4Qt protected: virtual void append(const LoggingEvent &rEvent); + virtual void asyncAppend(const LoggingEvent &rEvent); /*! * Tests if all entry conditions for using append() in this class are diff --git a/src/log4qt/log4qt/helpers/asyncdispatcher.cpp b/src/log4qt/log4qt/helpers/asyncdispatcher.cpp new file mode 100644 index 0000000..b0b3e83 --- /dev/null +++ b/src/log4qt/log4qt/helpers/asyncdispatcher.cpp @@ -0,0 +1,48 @@ +/* + * Copyright (C) 2021 Tianjin KYLIN Information Technology Co., Ltd. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see + +namespace Log4Qt +{ + +AsyncDispatcher::AsyncDispatcher(QObject *parent) : QObject(parent) + , mAsyncAppender(nullptr) +{} + +void AsyncDispatcher::customEvent(QEvent *event) +{ + if (event->type() == LoggingEvent::eventId) + { + auto *logEvent = static_cast(event); + if (mAsyncAppender != nullptr) + mAsyncAppender->asyncAppend(*logEvent); + } + QObject::customEvent(event); +} + +void AsyncDispatcher::setAsyncAppender(AppenderSkeleton *asyncAppender) +{ + mAsyncAppender = asyncAppender; +} + +} // namespace Log4Qt \ No newline at end of file diff --git a/src/log4qt/log4qt/helpers/asyncdispatcher.h b/src/log4qt/log4qt/helpers/asyncdispatcher.h new file mode 100644 index 0000000..91c30ce --- /dev/null +++ b/src/log4qt/log4qt/helpers/asyncdispatcher.h @@ -0,0 +1,55 @@ +/* + * Copyright (C) 2021 Tianjin KYLIN Information Technology Co., Ltd. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see +#include "ukui-logmacros.h" + +namespace Log4Qt +{ + +class AppenderSkeleton; + +/*! + * \brief The class AsyncDispatcher does the actual logging to the attached appanders. + * + * The Dispatcher is the worker object which class the attached apperders in the + * the context of the AsyncDispatcherThread. + * + * \note All the functions declared in this class are thread-safe. + */ +class LIBUKUILOG4QT_EXPORT AsyncDispatcher : public QObject +{ + Q_OBJECT +public: + explicit AsyncDispatcher(QObject *parent = nullptr); + + void setAsyncAppender(AppenderSkeleton *asyncAppender); + +protected: + void customEvent(QEvent *event) override; + +private: + AppenderSkeleton *mAsyncAppender; +}; + +} // namespace Log4Qt + +#endif // LOG4QT_ASYNCDISPATCHER_H diff --git a/src/log4qt/log4qt/log4qt.pri b/src/log4qt/log4qt/log4qt.pri index f9730b9..3c3b111 100644 --- a/src/log4qt/log4qt/log4qt.pri +++ b/src/log4qt/log4qt/log4qt.pri @@ -42,6 +42,7 @@ HEADERS += \ $$PWD/helpers/optionconverter.h \ $$PWD/helpers/patternformatter.h \ $$PWD/helpers/properties.h \ + $$PWD/helpers/asyncdispatcher.h \ $$PWD/hierarchy.h \ $$PWD/layout.h \ $$PWD/level.h \ @@ -84,6 +85,7 @@ SOURCES += \ $$PWD/helpers/optionconverter.cpp \ $$PWD/helpers/patternformatter.cpp \ $$PWD/helpers/properties.cpp \ + $$PWD/helpers/asyncdispatcher.cpp \ $$PWD/hierarchy.cpp \ $$PWD/layout.cpp \ $$PWD/level.cpp \ diff --git a/src/log4qt/log4qt/loggingevent.cpp b/src/log4qt/log4qt/loggingevent.cpp index 7570d20..753ede0 100644 --- a/src/log4qt/log4qt/loggingevent.cpp +++ b/src/log4qt/log4qt/loggingevent.cpp @@ -70,6 +70,7 @@ namespace Log4Qt LoggingEvent::LoggingEvent() : + QEvent(eventId), mLevel(Level::NULL_INT), mpLogger(0), mMessage(), @@ -86,6 +87,7 @@ namespace Log4Qt LoggingEvent::LoggingEvent(const Logger *pLogger, Level level, const QString &rMessage) : + QEvent(eventId), mLevel(level), mpLogger(pLogger), mMessage(rMessage), @@ -103,6 +105,7 @@ namespace Log4Qt Level level, const QString &rMessage, qint64 timeStamp) : + QEvent(eventId), mLevel(level), mpLogger(pLogger), mMessage(rMessage), @@ -123,6 +126,7 @@ namespace Log4Qt const QHash &rProperties, const QString &rThreadName, qint64 timeStamp) : + QEvent(eventId), mLevel(level), mpLogger(pLogger), mMessage(rMessage), @@ -184,7 +188,7 @@ namespace Log4Qt qint64 LoggingEvent::msSequenceCount = 0; - + const QEvent::Type LoggingEvent::eventId = static_cast(QEvent::registerEventType()); /************************************************************************** diff --git a/src/log4qt/log4qt/loggingevent.h b/src/log4qt/log4qt/loggingevent.h index 7b9568a..9d20ab1 100644 --- a/src/log4qt/log4qt/loggingevent.h +++ b/src/log4qt/log4qt/loggingevent.h @@ -34,6 +34,7 @@ #include #include #include +#include #include "log4qt/level.h" #include "ukui-logmacros.h" @@ -55,9 +56,10 @@ namespace Log4Qt * Universal Time for time values. For converstion from and to QDateTime * use DateTime. */ - class LIBUKUILOG4QT_EXPORT LoggingEvent + class LIBUKUILOG4QT_EXPORT LoggingEvent : public QEvent { public: + static const QEvent::Type eventId; LoggingEvent(); LoggingEvent(const Logger *pLogger, Level level, diff --git a/src/log4qt/log4qt/rollingfileappender.cpp b/src/log4qt/log4qt/rollingfileappender.cpp index 44f7bbe..53d527e 100644 --- a/src/log4qt/log4qt/rollingfileappender.cpp +++ b/src/log4qt/log4qt/rollingfileappender.cpp @@ -110,6 +110,17 @@ namespace Log4Qt // Q_ASSERT_X(, "RollingFileAppender::append()", "Lock must be held by caller") FileAppender::append(rEvent); + #ifndef UKUILOG4QT_EXTRA_ENABLE + if (writer()->device()->size() > this->mMaximumFileSize) + rollOver(); + #endif + } + + void RollingFileAppender::asyncAppend(const LoggingEvent &rEvent) + { + // Q_ASSERT_X(, "RollingFileAppender::asyncAppend()", "Lock must be held by caller") + + FileAppender::asyncAppend(rEvent); if (writer()->device()->size() > this->mMaximumFileSize) rollOver(); } diff --git a/src/log4qt/log4qt/rollingfileappender.h b/src/log4qt/log4qt/rollingfileappender.h index da008a9..5dafa22 100644 --- a/src/log4qt/log4qt/rollingfileappender.h +++ b/src/log4qt/log4qt/rollingfileappender.h @@ -101,6 +101,7 @@ namespace Log4Qt protected: virtual void append(const LoggingEvent &rEvent); + virtual void asyncAppend(const LoggingEvent &rEvent); #ifndef QT_NO_DEBUG_STREAM /*! diff --git a/src/log4qt/log4qt/varia/debugappender.cpp b/src/log4qt/log4qt/varia/debugappender.cpp index d4d0bd2..c30dac6 100644 --- a/src/log4qt/log4qt/varia/debugappender.cpp +++ b/src/log4qt/log4qt/varia/debugappender.cpp @@ -95,6 +95,28 @@ namespace Log4Qt fflush(stderr); #endif } + + void DebugAppender::asyncAppend(const LoggingEvent &rEvent) + { + // Q_ASSERT_X(, "DebugAppender::asyncAppend()", "Lock must be held by caller"); + Q_ASSERT_X(layout(), "DebugAppender::asyncAppend()", "Layout must not be null"); + + QString message(layout()->format(rEvent)); +#if defined(Q_OS_WIN32) || defined(Q_WS_WIN) + #if (QT_VERSION < 0x050000) + QT_WA({ + OutputDebugStringW(reinterpret_cast(message.utf16())); + }, { + OutputDebugStringA(message.toLocal8Bit().data()); + }); + #else + OutputDebugStringW(reinterpret_cast(message.utf16())); + #endif +#else + fprintf(stderr, "%s", message.toLocal8Bit().data()); + fflush(stderr); +#endif + } diff --git a/src/log4qt/log4qt/varia/debugappender.h b/src/log4qt/log4qt/varia/debugappender.h index e376ea7..e9479e9 100644 --- a/src/log4qt/log4qt/varia/debugappender.h +++ b/src/log4qt/log4qt/varia/debugappender.h @@ -94,6 +94,7 @@ namespace Log4Qt * \sa setLayout(), AppenderSkeleton::doAppend(), checkEntryConditions() */ virtual void append(const LoggingEvent &rEvent); + virtual void asyncAppend(const LoggingEvent &rEvent); #ifndef QT_NO_DEBUG_STREAM /*! diff --git a/src/log4qt/log4qt/varia/listappender.cpp b/src/log4qt/log4qt/varia/listappender.cpp index db20284..169c6b3 100644 --- a/src/log4qt/log4qt/varia/listappender.cpp +++ b/src/log4qt/log4qt/varia/listappender.cpp @@ -112,6 +112,14 @@ namespace Log4Qt if ((mMaxCount <= 0) || (mList.size() < mMaxCount)) mList << rEvent; } + + void ListAppender::asyncAppend(const LoggingEvent &rEvent) + { + // Q_ASSERT_X(, "ListAppender::asyncAppend()", "Lock must be held by caller") + + if ((mMaxCount <= 0) || (mList.size() < mMaxCount)) + mList << rEvent; + } #ifndef QT_NO_DEBUG_STREAM diff --git a/src/log4qt/log4qt/varia/listappender.h b/src/log4qt/log4qt/varia/listappender.h index 15d3159..54e6ae0 100644 --- a/src/log4qt/log4qt/varia/listappender.h +++ b/src/log4qt/log4qt/varia/listappender.h @@ -111,6 +111,7 @@ namespace Log4Qt protected: virtual void append(const LoggingEvent &rEvent); + virtual void asyncAppend(const LoggingEvent &rEvent); #ifndef QT_NO_DEBUG_STREAM /*! diff --git a/src/log4qt/log4qt/varia/nullappender.cpp b/src/log4qt/log4qt/varia/nullappender.cpp index a12ebf2..351a1a6 100644 --- a/src/log4qt/log4qt/varia/nullappender.cpp +++ b/src/log4qt/log4qt/varia/nullappender.cpp @@ -74,6 +74,11 @@ namespace Log4Qt { Q_UNUSED(rEvent); } + + void NullAppender::asyncAppend(const LoggingEvent &rEvent) + { + Q_UNUSED(rEvent); + } #ifndef QT_NO_DEBUG_STREAM diff --git a/src/log4qt/log4qt/varia/nullappender.h b/src/log4qt/log4qt/varia/nullappender.h index 8272174..d9697b6 100644 --- a/src/log4qt/log4qt/varia/nullappender.h +++ b/src/log4qt/log4qt/varia/nullappender.h @@ -64,6 +64,7 @@ class LIBUKUILOG4QT_EXPORT NullAppender : public AppenderSkeleton protected: virtual void append(const LoggingEvent &rEvent); + virtual void asyncAppend(const LoggingEvent &rEvent); #ifndef QT_NO_DEBUG_STREAM /*! diff --git a/src/log4qt/log4qt/writerappender.cpp b/src/log4qt/log4qt/writerappender.cpp index 25a633e..1421062 100644 --- a/src/log4qt/log4qt/writerappender.cpp +++ b/src/log4qt/log4qt/writerappender.cpp @@ -33,9 +33,11 @@ #include #include +#include +#include #include "log4qt/layout.h" #include "log4qt/loggingevent.h" - +#include "log4qt/helpers/asyncdispatcher.h" namespace Log4Qt @@ -63,7 +65,9 @@ namespace Log4Qt AppenderSkeleton(false, pParent), mpEncoding(0), mpWriter(0), - mImmediateFlush(true) + mImmediateFlush(true), + mThread(nullptr), + mAsyncDispatcher(nullptr) { } @@ -73,7 +77,9 @@ namespace Log4Qt AppenderSkeleton(false, pParent), mpEncoding(0), mpWriter(0), - mImmediateFlush(true) + mImmediateFlush(true), + mThread(nullptr), + mAsyncDispatcher(nullptr) { setLayout(pLayout); } @@ -85,7 +91,9 @@ namespace Log4Qt AppenderSkeleton(false, pParent), mpEncoding(0), mpWriter(pTextStream), - mImmediateFlush(true) + mImmediateFlush(true), + mThread(nullptr), + mAsyncDispatcher(nullptr) { setLayout(pLayout); } @@ -142,6 +150,15 @@ namespace Log4Qt } AppenderSkeleton::activateOptions(); + + if (mThread != nullptr) + return; + mThread = new QThread(); + mAsyncDispatcher = new AsyncDispatcher(); + mAsyncDispatcher->setAsyncAppender(this); + + mAsyncDispatcher->moveToThread(mThread); + //mThread->start(); } @@ -152,10 +169,27 @@ namespace Log4Qt if (isClosed()) return; + closeInternal(); AppenderSkeleton::close(); closeWriter(); } - + + void WriterAppender::closeInternal() + { + if (isClosed()) + return; + + if (mThread != nullptr) + { + mAsyncDispatcher->setAsyncAppender(nullptr); + mThread->quit(); + mThread->wait(); + delete mThread; + mThread = nullptr; + delete mAsyncDispatcher; + mAsyncDispatcher = nullptr; + } + } bool WriterAppender::requiresLayout() const { @@ -166,8 +200,32 @@ namespace Log4Qt void WriterAppender::append(const LoggingEvent &rEvent) { // Q_ASSERT_X(, "WriterAppender::append()", "Lock must be held by caller"); + #ifndef UKUILOG4QT_EXTRA_ENABLE Q_ASSERT_X(layout(), "WriterAppender::append()", "Layout must not be null"); + QString message(layout()->format(rEvent)); + *mpWriter << message; + if (handleIoErrors()) + return; + + if (immediateFlush()) + { + mpWriter->flush(); + if (handleIoErrors()) + return; + } + #else + if (mThread && !mThread->isRunning()) + mThread->start(); + if (qApp) + qApp->postEvent(mAsyncDispatcher, new LoggingEvent(rEvent)); + #endif + } + + void WriterAppender::asyncAppend(const LoggingEvent &rEvent) + { + // Q_ASSERT_X(, "WriterAppender::asyncAppend()", "Lock must be held by caller"); + Q_ASSERT_X(layout(), "WriterAppender::asyncAppend()", "Layout must not be null"); QString message(layout()->format(rEvent)); *mpWriter << message; diff --git a/src/log4qt/log4qt/writerappender.h b/src/log4qt/log4qt/writerappender.h index ca2e087..8d5e7b8 100644 --- a/src/log4qt/log4qt/writerappender.h +++ b/src/log4qt/log4qt/writerappender.h @@ -43,7 +43,8 @@ class QTextStream; namespace Log4Qt { - + class AsyncDispatcher; + /*! * \brief The class WriterAppender appends log events to a QTextStream. * @@ -92,6 +93,7 @@ namespace Log4Qt private: WriterAppender(const WriterAppender &rOther); // Not implemented WriterAppender &operator=(const WriterAppender &rOther); // Not implemented + void closeInternal(); public: virtual bool requiresLayout() const; @@ -117,6 +119,7 @@ namespace Log4Qt protected: virtual void append(const LoggingEvent &rEvent); + virtual void asyncAppend(const LoggingEvent &rEvent); /*! * Tests if all entry conditions for using append() in this class are @@ -163,6 +166,9 @@ namespace Log4Qt QTextCodec *mpEncoding; QTextStream *mpWriter; volatile bool mImmediateFlush; + //! Event dispatcher trhead + QThread *mThread; + AsyncDispatcher *mAsyncDispatcher; }; diff --git a/src/log4qt/ukui-log4qt.pro b/src/log4qt/ukui-log4qt.pro index 5025e0c..0fdcc49 100644 --- a/src/log4qt/ukui-log4qt.pro +++ b/src/log4qt/ukui-log4qt.pro @@ -1,7 +1,7 @@ QT -= gui TEMPLATE = lib -DEFINES += LIBUKUILOG4QT_LIBRARY +DEFINES += LIBUKUILOG4QT_LIBRARY UKUILOG4QT_EXTRA_ENABLE CONFIG += link_pkgconfig \ c++11 From 93b75a45a6b037cd86a69486f6f7f55b6b8ea7b0 Mon Sep 17 00:00:00 2001 From: winnerym100 Date: Tue, 20 Apr 2021 12:52:57 +0800 Subject: [PATCH 06/35] =?UTF-8?q?fix=EF=BC=9A=E4=BF=AE=E5=A4=8D=E8=A3=85?= =?UTF-8?q?=E5=8C=85=E4=BE=9D=E8=B5=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- debian/changelog | 12 ++++++++++++ debian/control | 5 +++-- src/log4qt/log4qt/writerappender.cpp | 7 ++++--- 3 files changed, 19 insertions(+), 5 deletions(-) diff --git a/debian/changelog b/debian/changelog index 19948c1..c1db4a1 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,15 @@ +ukui-interface (1.0.1-5) v101; urgency=medium + + * fix:修复装包依赖libglib2.0-bin + + -- Yang Min Tue, 20 Apr 2021 12:36:27 +0800 + +ukui-interface (1.0.1-4) v101; urgency=medium + + * fix:升版本重编 + + -- Yang Min Mon, 19 Apr 2021 16:43:41 +0800 + ukui-interface (1.0.1-3) v101; urgency=medium * feature: 日志异步输出 diff --git a/debian/control b/debian/control index 4bed371..aa0c187 100644 --- a/debian/control +++ b/debian/control @@ -606,7 +606,7 @@ Description: xkbgeneral settings interfaces Package: libukui-log4qt0 Architecture: any -Depends: ${shlibs:Depends}, ${misc:Depends} +Depends: ${shlibs:Depends}, ${misc:Depends}, libglib2.0-bin Description: log4qt module UKUI interface provides the interface for system configuration and related libraries. @@ -618,7 +618,8 @@ Architecture: any Section: libdevel Depends: ${shlibs:Depends}, ${misc:Depends}, - libukui-log4qt0 (= ${binary:Version}) + libukui-log4qt0 (= ${binary:Version}), + libglib2.0-bin Description: log4qt interface UKUI interface provides the interface for system configuration and related libraries. diff --git a/src/log4qt/log4qt/writerappender.cpp b/src/log4qt/log4qt/writerappender.cpp index 1421062..27fc637 100644 --- a/src/log4qt/log4qt/writerappender.cpp +++ b/src/log4qt/log4qt/writerappender.cpp @@ -215,10 +215,11 @@ namespace Log4Qt return; } #else - if (mThread && !mThread->isRunning()) - mThread->start(); - if (qApp) + if (qApp) { + if (mThread && !mThread->isRunning()) + mThread->start(); qApp->postEvent(mAsyncDispatcher, new LoggingEvent(rEvent)); + } #endif } From 08bc24a0ab1db1f3ec127b019b33173e1973f0d3 Mon Sep 17 00:00:00 2001 From: winnerym100 Date: Tue, 20 Apr 2021 18:37:52 +0800 Subject: [PATCH 07/35] =?UTF-8?q?=E4=BC=98=E5=8C=96=E5=8A=9F=E8=83=BD?= =?UTF-8?q?=EF=BC=9A=E6=97=A5=E5=BF=97=E7=BA=A7=E5=88=AB=E8=AE=BE=E7=BD=AE?= =?UTF-8?q?=E4=B8=8D=E5=8C=BA=E5=88=86=E5=A4=A7=E5=B0=8F=E5=86=99=EF=BC=8C?= =?UTF-8?q?=E9=BB=98=E8=AE=A4=E6=97=A5=E5=BF=97=E7=BA=A7=E5=88=AB=E4=B8=BA?= =?UTF-8?q?OFF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/log4qt/log4qt/level.cpp | 40 ++++++++++++++++++++++++++++++++++--- 1 file changed, 37 insertions(+), 3 deletions(-) diff --git a/src/log4qt/log4qt/level.cpp b/src/log4qt/log4qt/level.cpp index a55038f..9188581 100644 --- a/src/log4qt/log4qt/level.cpp +++ b/src/log4qt/log4qt/level.cpp @@ -126,8 +126,41 @@ namespace Log4Qt const char *p_context = "Level"; if (pOk) *pOk = true; - - if (rLevel == QLatin1String("OFF") || + #if 1 + if (!rLevel.compare(QLatin1String("OFF"), Qt::CaseInsensitive) || + !rLevel.compare(QCoreApplication::translate(p_context, "OFF"), Qt::CaseInsensitive)) + return OFF_INT; + if (!rLevel.compare(QLatin1String("FATAL"), Qt::CaseInsensitive) || + !rLevel.compare(QCoreApplication::translate(p_context, "FATAL"), Qt::CaseInsensitive)) + return FATAL_INT; + if (!rLevel.compare(QLatin1String("ERROR"), Qt::CaseInsensitive) || + !rLevel.compare(QCoreApplication::translate(p_context, "ERROR"), Qt::CaseInsensitive)) + return ERROR_INT; + if (!rLevel.compare(QLatin1String("WARN"), Qt::CaseInsensitive) || + !rLevel.compare(QCoreApplication::translate(p_context, "WARN"), Qt::CaseInsensitive)) + return WARN_INT; + if (!rLevel.compare(QLatin1String("INFO"), Qt::CaseInsensitive) || + !rLevel.compare(QCoreApplication::translate(p_context, "INFO"), Qt::CaseInsensitive)) + return INFO_INT; + if (!rLevel.compare(QLatin1String("DEBUG"), Qt::CaseInsensitive) || + !rLevel.compare(QCoreApplication::translate(p_context, "DEBUG"), Qt::CaseInsensitive)) + return DEBUG_INT; + if (!rLevel.compare(QLatin1String("TRACE"), Qt::CaseInsensitive) || + !rLevel.compare(QCoreApplication::translate(p_context, "TRACE"), Qt::CaseInsensitive)) + return TRACE_INT; + if (!rLevel.compare(QLatin1String("ALL"), Qt::CaseInsensitive) || + !rLevel.compare(QCoreApplication::translate(p_context, "ALL"), Qt::CaseInsensitive)) + return ALL_INT; + if (!rLevel.compare(QLatin1String("NULL"), Qt::CaseInsensitive) || + !rLevel.compare(QCoreApplication::translate(p_context, "NULL"), Qt::CaseInsensitive)) + return NULL_INT; + + logger()->warn("Use of invalid level string '%1'. Using 'Level::OFF_INT' instead.", rLevel); + if (pOk) + *pOk = false; + return OFF_INT; + #else + if (rLevel == QLatin1String("OFF") || rLevel == QCoreApplication::translate(p_context, "OFF")) return OFF_INT; if (rLevel == QLatin1String("FATAL") || @@ -154,11 +187,12 @@ namespace Log4Qt if (rLevel == QLatin1String("NULL") || rLevel == QCoreApplication::translate(p_context, "NULL")) return NULL_INT; - + logger()->warn("Use of invalid level string '%1'. Using 'Level::NULL_INT' instead.", rLevel); if (pOk) *pOk = false; return NULL_INT; + #endif } From 2a0ca1f934e1c42abab9be5d421c84517d05ef86 Mon Sep 17 00:00:00 2001 From: winnerym100 Date: Mon, 10 May 2021 14:40:27 +0800 Subject: [PATCH 08/35] =?UTF-8?q?fix:=E4=BF=AE=E5=A4=8D=E5=9C=A8SW?= =?UTF-8?q?=E6=9E=B6=E6=9E=84=E4=B8=8AQFileInfo=E8=8E=B7=E5=8F=96=E4=B8=8D?= =?UTF-8?q?=E5=88=B0birthTime=E6=97=B6=E4=BC=9A=E5=AF=BC=E8=87=B4=E7=A8=8B?= =?UTF-8?q?=E5=BA=8F=E5=B4=A9=E6=BA=83=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- debian/changelog | 8 +++++++ .../log4qt/dailyrollingfileappender.cpp | 2 +- src/log4qt/log4qt/fileappender.cpp | 3 +++ src/log4qt/log4qt/writerappender.cpp | 23 +++++++++++++++++++ 4 files changed, 35 insertions(+), 1 deletion(-) diff --git a/debian/changelog b/debian/changelog index c1db4a1..09bfb25 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,11 @@ +ukui-interface (1.0.1-7) v101; urgency=medium + + * BUG号:无 + * 需求号:无 + * 其他改动说明:修复在SW架构上QFileInfo获取不到birthTime时会导致程序崩溃问题 + + -- Yang Min Sat, 08 May 2021 15:29:14 +0800 + ukui-interface (1.0.1-5) v101; urgency=medium * fix:修复装包依赖libglib2.0-bin diff --git a/src/log4qt/log4qt/dailyrollingfileappender.cpp b/src/log4qt/log4qt/dailyrollingfileappender.cpp index 19f50e2..682f8d5 100644 --- a/src/log4qt/log4qt/dailyrollingfileappender.cpp +++ b/src/log4qt/log4qt/dailyrollingfileappender.cpp @@ -129,7 +129,7 @@ namespace Log4Qt if (!fileInfo.exists()) { computeRollOverTime(); } else { - computeRollOverTime(fileInfo.birthTime()); + computeRollOverTime(fileInfo.birthTime().isNull()?fileInfo.lastModified():fileInfo.birthTime()); } #else computeRollOverTime(); diff --git a/src/log4qt/log4qt/fileappender.cpp b/src/log4qt/log4qt/fileappender.cpp index 265634f..77db664 100644 --- a/src/log4qt/log4qt/fileappender.cpp +++ b/src/log4qt/log4qt/fileappender.cpp @@ -286,6 +286,9 @@ namespace Log4Qt const QString &rFileName) const { logger()->debug("Renaming file '%1' to '%2'", rFile.fileName(), rFileName); + if (!rFileName.compare(rFile.fileName())) + return true; + if (rFile.rename(rFileName)) return true; diff --git a/src/log4qt/log4qt/writerappender.cpp b/src/log4qt/log4qt/writerappender.cpp index 27fc637..b434dc4 100644 --- a/src/log4qt/log4qt/writerappender.cpp +++ b/src/log4qt/log4qt/writerappender.cpp @@ -203,6 +203,9 @@ namespace Log4Qt #ifndef UKUILOG4QT_EXTRA_ENABLE Q_ASSERT_X(layout(), "WriterAppender::append()", "Layout must not be null"); QString message(layout()->format(rEvent)); + + if (!mpWriter) + return; *mpWriter << message; if (handleIoErrors()) @@ -219,6 +222,23 @@ namespace Log4Qt if (mThread && !mThread->isRunning()) mThread->start(); qApp->postEvent(mAsyncDispatcher, new LoggingEvent(rEvent)); + } else { + Q_ASSERT_X(layout(), "WriterAppender::append()", "Layout must not be null"); + QString message(layout()->format(rEvent)); + + if (!mpWriter) + return; + + *mpWriter << message; + if (handleIoErrors()) + return; + + if (immediateFlush()) + { + mpWriter->flush(); + if (handleIoErrors()) + return; + } } #endif } @@ -228,6 +248,9 @@ namespace Log4Qt // Q_ASSERT_X(, "WriterAppender::asyncAppend()", "Lock must be held by caller"); Q_ASSERT_X(layout(), "WriterAppender::asyncAppend()", "Layout must not be null"); QString message(layout()->format(rEvent)); + + if (!mpWriter) + return; *mpWriter << message; if (handleIoErrors()) From f4f5a84fc79afbcdaca95dffe0e75e91bc8ecfeb Mon Sep 17 00:00:00 2001 From: winnerym100 Date: Mon, 24 May 2021 21:06:48 +0800 Subject: [PATCH 09/35] =?UTF-8?q?=E4=BC=98=E5=8C=96=E5=8A=9F=E8=83=BD?= =?UTF-8?q?=EF=BC=9A=E4=BC=98=E5=8C=96=E5=BD=93=E5=89=8D=E6=97=A5=E5=BF=97?= =?UTF-8?q?=E6=96=87=E4=BB=B6=E8=B6=85=E8=BF=87=E9=99=90=E5=88=B6=E5=A4=A7?= =?UTF-8?q?=E5=B0=8F=E6=97=B6=E6=B8=85=E7=A9=BA=E9=80=BB=E8=BE=91=EF=BC=9B?= =?UTF-8?q?=E4=BF=AE=E5=A4=8Dbug=EF=BC=9A=E4=BF=AE=E5=A4=8Dfork=E5=AD=90?= =?UTF-8?q?=E8=BF=9B=E7=A8=8B=E5=90=8E=EF=BC=8C=E5=AD=90=E8=BF=9B=E7=A8=8B?= =?UTF-8?q?=E6=97=A5=E5=BF=97=E6=97=A0=E6=B3=95=E8=BE=93=E5=87=BA=E9=97=AE?= =?UTF-8?q?=E9=A2=98=EF=BC=9B=E4=BF=AE=E6=94=B9=E5=8A=9F=E8=83=BD=EF=BC=9A?= =?UTF-8?q?=E4=BF=AE=E6=94=B9=E6=97=A5=E5=BF=97=E6=96=87=E4=BB=B6=E7=9B=AE?= =?UTF-8?q?=E5=BD=95=E4=B8=BA~/.log/?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- debian/changelog | 10 ++++++++++ src/log4qt/log4qt/writerappender.cpp | 5 +++-- src/log4qt/ukui-logconfigurator.cpp | 3 +++ src/log4qt/ukui-logmacros.h | 2 +- src/log4qt/ukui-logrolling.cpp | 6 ++++++ 5 files changed, 23 insertions(+), 3 deletions(-) diff --git a/debian/changelog b/debian/changelog index 09bfb25..e683f6a 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,13 @@ +ukui-interface (1.0.1-8) v101; urgency=medium + + * BUG号:无 + * 需求号:无 + * 其他改动说明:1、优化当前日志文件超过限制大小时清空逻辑; + 2、修复fork子进程后,子进程日志无法输出问题; + 3、修改日志文件目录为~/.log/ + + -- Yang Min Mon, 24 May 2021 20:59:37 +0800 + ukui-interface (1.0.1-7) v101; urgency=medium * BUG号:无 diff --git a/src/log4qt/log4qt/writerappender.cpp b/src/log4qt/log4qt/writerappender.cpp index b434dc4..a2e2f94 100644 --- a/src/log4qt/log4qt/writerappender.cpp +++ b/src/log4qt/log4qt/writerappender.cpp @@ -35,11 +35,12 @@ #include #include #include +#include #include "log4qt/layout.h" #include "log4qt/loggingevent.h" #include "log4qt/helpers/asyncdispatcher.h" - +extern pid_t g_MainProcPid; namespace Log4Qt { @@ -218,7 +219,7 @@ namespace Log4Qt return; } #else - if (qApp) { + if (qApp && g_MainProcPid == getpid()) { if (mThread && !mThread->isRunning()) mThread->start(); qApp->postEvent(mAsyncDispatcher, new LoggingEvent(rEvent)); diff --git a/src/log4qt/ukui-logconfigurator.cpp b/src/log4qt/ukui-logconfigurator.cpp index 624ab14..a7a0f5b 100644 --- a/src/log4qt/ukui-logconfigurator.cpp +++ b/src/log4qt/ukui-logconfigurator.cpp @@ -27,10 +27,12 @@ #include #include +#include LOG4QT_GLOBAL_STATIC(QMutex, single_config) UkuiLog4qtConfig *UkuiLog4qtConfig::mInstance = nullptr; +pid_t g_MainProcPid = -1; UkuiLog4qtConfig::UkuiLog4qtConfig(QObject *parent) : QObject(parent), @@ -43,6 +45,7 @@ UkuiLog4qtConfig::UkuiLog4qtConfig(QObject *parent) : m_uMaxFileCount = 0; m_uMaxFileSize = 0; m_timeCheckFile = 60; + g_MainProcPid = getpid(); } UkuiLog4qtConfig::~UkuiLog4qtConfig() diff --git a/src/log4qt/ukui-logmacros.h b/src/log4qt/ukui-logmacros.h index 65a4a76..b637ac9 100644 --- a/src/log4qt/ukui-logmacros.h +++ b/src/log4qt/ukui-logmacros.h @@ -28,7 +28,7 @@ #endif // 日志文件相对home目录路径 -#define UKUILOG4QT_ROOTPATH "/.config/ukui/" +#define UKUILOG4QT_ROOTPATH "/.log/" // gsettings相关相关属性 #define UKUILOG4QT_SETTINGS "org.ukui.ukui-log4qt" diff --git a/src/log4qt/ukui-logrolling.cpp b/src/log4qt/ukui-logrolling.cpp index b31c6b3..35ba744 100644 --- a/src/log4qt/ukui-logrolling.cpp +++ b/src/log4qt/ukui-logrolling.cpp @@ -23,6 +23,7 @@ #include #include #include +#include UkuiLog4qtRolling::UkuiLog4qtRolling(QString strBaseFilePath, unsigned uMaxFileCount, quint64 uMaxFileSize, quint64 delayCheckFileTime, QObject *parent) : @@ -170,6 +171,11 @@ void UkuiLog4qtRolling::checkLogFilesSize() QFile file(filePath); file.remove(); // 删除文件 willRmFileSize -= fileInfoList[i].size(); + } else { // 清空文件内容 + //KyDebug()<<"清空文件内容:"< %1").arg(filePath)); + process.waitForFinished(100); } } } \ No newline at end of file From 20bd87519caa7684e6c66193eaed01be7e9e28de Mon Sep 17 00:00:00 2001 From: winnerym100 Date: Fri, 11 Jun 2021 19:44:43 +0800 Subject: [PATCH 10/35] =?UTF-8?q?feature:log4qt=E6=97=A5=E5=BF=97=E4=BF=A1?= =?UTF-8?q?=E6=81=AF=E4=B8=AD=E5=A2=9E=E5=8A=A0=E8=BF=9B=E7=A8=8BID?= =?UTF-8?q?=E4=BF=A1=E6=81=AF=EF=BC=9Bfix:=E4=BF=AE=E5=A4=8Dlog4qt?= =?UTF-8?q?=E5=81=B6=E7=8E=B0=E9=87=8A=E6=94=BE=E8=B5=84=E6=BA=90=E6=97=B6?= =?UTF-8?q?=E5=8D=A1=E4=BD=8F=E5=AF=BC=E8=87=B4=E8=BF=9B=E7=A8=8B=E6=97=A0?= =?UTF-8?q?=E6=B3=95=E6=AD=A3=E5=B8=B8=E7=BB=93=E6=9D=9F=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- debian/changelog | 9 +++++ src/log4qt/log4qt/logmanager.cpp | 11 +++--- src/log4qt/log4qt/writerappender.cpp | 57 ++-------------------------- src/log4qt/log4qt/writerappender.h | 3 -- 4 files changed, 18 insertions(+), 62 deletions(-) diff --git a/debian/changelog b/debian/changelog index e683f6a..d175b79 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,12 @@ +ukui-interface (1.0.1-9hw1) v101.hw; urgency=medium + + * BUG号:无 + * 需求号:无 + * 其他改动说明:1、修复log4qt日志库偶现释放资源时因等待线程退出阻塞进程退出问题; + 2、辅助修复55965、59160bug中ukui-session偶现卡住问题 + + -- Yang Min Fri, 11 Jun 2021 19:34:53 +0800 + ukui-interface (1.0.1-8) v101; urgency=medium * BUG号:无 diff --git a/src/log4qt/log4qt/logmanager.cpp b/src/log4qt/log4qt/logmanager.cpp index 992ece5..f1b478f 100644 --- a/src/log4qt/log4qt/logmanager.cpp +++ b/src/log4qt/log4qt/logmanager.cpp @@ -54,6 +54,7 @@ #include "log4qt/varia/denyallfilter.h" #include "log4qt/varia/levelrangefilter.h" +#include namespace Log4Qt { @@ -415,9 +416,9 @@ namespace Log4Qt #endif #if defined(Q_OS_UNIX) && defined(QT_DEBUG) - abort(); // trap; generates core dump + //abort(); // trap; generates core dump #else - exit(1); // goodbye cruel world + //exit(1); // goodbye cruel world #endif } @@ -447,7 +448,7 @@ namespace Log4Qt default: level = Level::TRACE_INT; } - QString newMsg = context.file?QString("%1:%2(%3)|").arg(context.file).arg(context.line).arg(context.function):"|"; + QString newMsg = context.file?QString("|PID:%1|%2:%3(%4)|").arg(getpid()).arg(context.file).arg(context.line).arg(context.function):QString("|PID:%1|").arg(getpid()); instance()->qtLogger()->log(level, newMsg+message); // Qt fatal behaviour copied from global.cpp qt_message_output() @@ -468,9 +469,9 @@ namespace Log4Qt #endif #if defined(Q_OS_UNIX) && defined(QT_DEBUG) - abort(); // trap; generates core dump + //abort(); // trap; generates core dump #else - exit(1); // goodbye cruel world + //exit(1); // goodbye cruel world #endif } diff --git a/src/log4qt/log4qt/writerappender.cpp b/src/log4qt/log4qt/writerappender.cpp index a2e2f94..f1be768 100644 --- a/src/log4qt/log4qt/writerappender.cpp +++ b/src/log4qt/log4qt/writerappender.cpp @@ -66,9 +66,7 @@ namespace Log4Qt AppenderSkeleton(false, pParent), mpEncoding(0), mpWriter(0), - mImmediateFlush(true), - mThread(nullptr), - mAsyncDispatcher(nullptr) + mImmediateFlush(true) { } @@ -78,9 +76,7 @@ namespace Log4Qt AppenderSkeleton(false, pParent), mpEncoding(0), mpWriter(0), - mImmediateFlush(true), - mThread(nullptr), - mAsyncDispatcher(nullptr) + mImmediateFlush(true) { setLayout(pLayout); } @@ -92,9 +88,7 @@ namespace Log4Qt AppenderSkeleton(false, pParent), mpEncoding(0), mpWriter(pTextStream), - mImmediateFlush(true), - mThread(nullptr), - mAsyncDispatcher(nullptr) + mImmediateFlush(true) { setLayout(pLayout); } @@ -151,15 +145,6 @@ namespace Log4Qt } AppenderSkeleton::activateOptions(); - - if (mThread != nullptr) - return; - mThread = new QThread(); - mAsyncDispatcher = new AsyncDispatcher(); - mAsyncDispatcher->setAsyncAppender(this); - - mAsyncDispatcher->moveToThread(mThread); - //mThread->start(); } @@ -179,17 +164,6 @@ namespace Log4Qt { if (isClosed()) return; - - if (mThread != nullptr) - { - mAsyncDispatcher->setAsyncAppender(nullptr); - mThread->quit(); - mThread->wait(); - delete mThread; - mThread = nullptr; - delete mAsyncDispatcher; - mAsyncDispatcher = nullptr; - } } bool WriterAppender::requiresLayout() const @@ -201,7 +175,6 @@ namespace Log4Qt void WriterAppender::append(const LoggingEvent &rEvent) { // Q_ASSERT_X(, "WriterAppender::append()", "Lock must be held by caller"); - #ifndef UKUILOG4QT_EXTRA_ENABLE Q_ASSERT_X(layout(), "WriterAppender::append()", "Layout must not be null"); QString message(layout()->format(rEvent)); @@ -218,30 +191,6 @@ namespace Log4Qt if (handleIoErrors()) return; } - #else - if (qApp && g_MainProcPid == getpid()) { - if (mThread && !mThread->isRunning()) - mThread->start(); - qApp->postEvent(mAsyncDispatcher, new LoggingEvent(rEvent)); - } else { - Q_ASSERT_X(layout(), "WriterAppender::append()", "Layout must not be null"); - QString message(layout()->format(rEvent)); - - if (!mpWriter) - return; - - *mpWriter << message; - if (handleIoErrors()) - return; - - if (immediateFlush()) - { - mpWriter->flush(); - if (handleIoErrors()) - return; - } - } - #endif } void WriterAppender::asyncAppend(const LoggingEvent &rEvent) diff --git a/src/log4qt/log4qt/writerappender.h b/src/log4qt/log4qt/writerappender.h index 8d5e7b8..9961c5e 100644 --- a/src/log4qt/log4qt/writerappender.h +++ b/src/log4qt/log4qt/writerappender.h @@ -166,9 +166,6 @@ namespace Log4Qt QTextCodec *mpEncoding; QTextStream *mpWriter; volatile bool mImmediateFlush; - //! Event dispatcher trhead - QThread *mThread; - AsyncDispatcher *mAsyncDispatcher; }; From 43157c52066f36e9c81ce5e653345c7ca5e86f66 Mon Sep 17 00:00:00 2001 From: handsome-feng Date: Thu, 17 Jun 2021 15:25:51 +0800 Subject: [PATCH 11/35] 1.0.1-1 --- debian/changelog | 63 +++--------------------------------------------- 1 file changed, 3 insertions(+), 60 deletions(-) diff --git a/debian/changelog b/debian/changelog index d175b79..b6640eb 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,65 +1,8 @@ -ukui-interface (1.0.1-9hw1) v101.hw; urgency=medium +ukui-interface (1.0.1-1) focal; urgency=medium - * BUG号:无 - * 需求号:无 - * 其他改动说明:1、修复log4qt日志库偶现释放资源时因等待线程退出阻塞进程退出问题; - 2、辅助修复55965、59160bug中ukui-session偶现卡住问题 + * New upstream release. - -- Yang Min Fri, 11 Jun 2021 19:34:53 +0800 - -ukui-interface (1.0.1-8) v101; urgency=medium - - * BUG号:无 - * 需求号:无 - * 其他改动说明:1、优化当前日志文件超过限制大小时清空逻辑; - 2、修复fork子进程后,子进程日志无法输出问题; - 3、修改日志文件目录为~/.log/ - - -- Yang Min Mon, 24 May 2021 20:59:37 +0800 - -ukui-interface (1.0.1-7) v101; urgency=medium - - * BUG号:无 - * 需求号:无 - * 其他改动说明:修复在SW架构上QFileInfo获取不到birthTime时会导致程序崩溃问题 - - -- Yang Min Sat, 08 May 2021 15:29:14 +0800 - -ukui-interface (1.0.1-5) v101; urgency=medium - - * fix:修复装包依赖libglib2.0-bin - - -- Yang Min Tue, 20 Apr 2021 12:36:27 +0800 - -ukui-interface (1.0.1-4) v101; urgency=medium - - * fix:升版本重编 - - -- Yang Min Mon, 19 Apr 2021 16:43:41 +0800 - -ukui-interface (1.0.1-3) v101; urgency=medium - - * feature: 日志异步输出 - - -- Yang Min Sat, 17 Apr 2021 16:59:43 +0800 - -ukui-interface (1.0.1-2) v101; urgency=medium - - * 修复bug:修复隔天重新打开程序时日志文件未按日期分割 - - -- Yang Min Fri, 16 Apr 2021 15:38:18 +0800 - -ukui-interface (1.0.1-1) v101; urgency=medium - - * 完善功能:将qt日志库默认配置文件打包进deb - - -- Yang Min Sat, 10 Apr 2021 14:32:55 +0800 - -ukui-interface (1.0.1) v101; urgency=medium - - * 增加功能:增加qt日志打印包 - - -- Yang Min Sat, 10 Apr 2021 11:49:30 +0800 + -- handsome_feng Thu, 17 Jun 2021 15:23:30 +0800 ukui-interface (1.0.0-2) unstable; urgency=low From b1775073f1cd51b29fa140e91f35d2148a15d075 Mon Sep 17 00:00:00 2001 From: handsome-feng Date: Thu, 17 Jun 2021 23:39:15 +0800 Subject: [PATCH 12/35] 1.0.1.1-1: no changes --- debian/changelog | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/debian/changelog b/debian/changelog index b6640eb..a781a6b 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,4 +1,4 @@ -ukui-interface (1.0.1-1) focal; urgency=medium +ukui-interface (1.0.1.1-1) focal; urgency=medium * New upstream release. From 853b0a75c3420e3fa3f98fd354e751f6235d624a Mon Sep 17 00:00:00 2001 From: kevin Date: Mon, 12 Jul 2021 16:59:56 +0800 Subject: [PATCH 13/35] Fix lintian error --- debian/copyright | 21 +++++---- debian/libukui-log4qt0.postinst | 1 + debian/upstream/metadata | 3 -- debian/watch | 3 -- src/log4qt/debian/changelog | 11 ----- src/log4qt/debian/control | 25 ----------- src/log4qt/debian/copyright | 45 -------------------- src/log4qt/debian/libukui-log4qt-dev.install | 1 - src/log4qt/debian/rules | 6 --- src/log4qt/debian/source/format | 1 - 10 files changed, 11 insertions(+), 106 deletions(-) delete mode 100644 debian/upstream/metadata delete mode 100644 debian/watch delete mode 100644 src/log4qt/debian/changelog delete mode 100644 src/log4qt/debian/control delete mode 100644 src/log4qt/debian/copyright delete mode 100644 src/log4qt/debian/libukui-log4qt-dev.install delete mode 100755 src/log4qt/debian/rules delete mode 100644 src/log4qt/debian/source/format diff --git a/debian/copyright b/debian/copyright index f422f50..6ffd241 100644 --- a/debian/copyright +++ b/debian/copyright @@ -3,10 +3,13 @@ Upstream-Name: ukui-interface Upstream-Contact: liuhao Source: https://github.com/ukui/ukui-interface +Files: * +Copyright: 2019 Tianjin KYLIN Information Technology Co., Ltd. +License: GPL-3.0+ + Files: src/log4qt/doc/* - src/log4qt/log4qt/* - src/log4qt/src/log4qt/* - src/log4qt/tests/* + src/log4qt/log4qt/* + src/log4qt/tests/* Copyright: 2007 - 2009 Martin Heinrich License: Apache-2.0 Licensed under the Apache License, Version 2.0 (the "License"); @@ -26,18 +29,14 @@ License: Apache-2.0 Files: src/log4qt/ukui-log4qt.h src/log4qt/ukui-log4qt.cpp - src/log4qt/ukui-ukui-logconfigurator.h - src/log4qt/ukui-ukui-logconfigurator.cpp - src/log4qt/ukui-ukui-logrolling.h - src/log4qt/ukui-ukui-logrolling.cpp + src/log4qt/ukui-logconfigurator.h + src/log4qt/ukui-logconfigurator.cpp + src/log4qt/ukui-logrolling.h + src/log4qt/ukui-logrolling.cpp src/log4qt/ukui-logmacros.h Copyright: 2021 Yang Min License: GPL-3.0+ -Files: * -Copyright: 2019 Tianjin KYLIN Information Technology Co., Ltd. -License: GPL-3.0+ - Files: debian/* Copyright: 2019 liuhao License: GPL-3.0+ diff --git a/debian/libukui-log4qt0.postinst b/debian/libukui-log4qt0.postinst index cca3fa9..d370a3f 100644 --- a/debian/libukui-log4qt0.postinst +++ b/debian/libukui-log4qt0.postinst @@ -1,4 +1,5 @@ #!/bin/sh +set -e glib-compile-schemas /usr/share/glib-2.0/schemas/ diff --git a/debian/upstream/metadata b/debian/upstream/metadata deleted file mode 100644 index 5840756..0000000 --- a/debian/upstream/metadata +++ /dev/null @@ -1,3 +0,0 @@ ---- -Bug-Database: https://github.com/ukui/ukui-interface/issues -Bug-Submit: https://github.com/ukui/ukui-interface/issues/new diff --git a/debian/watch b/debian/watch deleted file mode 100644 index a0d6f97..0000000 --- a/debian/watch +++ /dev/null @@ -1,3 +0,0 @@ -version=4 -opts=filenamemangle=s/.+\/v?(\d\S+)\.tar\.gz/ukui-interface-$1\.tar\.gz/ \ - https://github.com/ukui/ukui-interface/releases .*/v?(\d\S+)\.tar\.gz diff --git a/src/log4qt/debian/changelog b/src/log4qt/debian/changelog deleted file mode 100644 index 981557d..0000000 --- a/src/log4qt/debian/changelog +++ /dev/null @@ -1,11 +0,0 @@ -log4qt (1.0.1) v101; urgency=medium - - * Fix:修复qt开启宏QT_NO_DEBUG时log输出的代码位置信息为空异常 - - -- Yang Min Tue, 30 Mar 2021 19:25:20 +0800 - -log4qt (1.0.0) v101; urgency=medium - - * Initial release. - - -- Yang Min Tue, 30 Mar 2021 16:29:55 +0800 diff --git a/src/log4qt/debian/control b/src/log4qt/debian/control deleted file mode 100644 index 43e560f..0000000 --- a/src/log4qt/debian/control +++ /dev/null @@ -1,25 +0,0 @@ -Source: log4qt -Section: libs -Priority: optional -Maintainer: Kylin Team -Uploaders: Yang Min -Build-Depends: debhelper-compat (=12), - qt5-qmake, - qtbase5-dev, - qtbase5-dev-tools, - qtbase5-private-dev, - libgsettings-qt-dev -Standards-Version: 4.5.1 -Rules-Requires-Root: no -Homepage: https://sourceforge.net/projects/log4qt/files/ -Vcs-Git: https://github.com/devbean/log4qt.git -Vcs-Browser: https://github.com/devbean/log4qt - -Package: libukui-log4qt-dev -Section: libdevel -Architecture: any -Depends: ${misc:Depends}, - ${shlibs:Depends} -Description: Development files for the Log4Qt library - Log4Qt is a C++ port of the Apache Software Foundation - Log4j package using the Trolltech Qt Framework. diff --git a/src/log4qt/debian/copyright b/src/log4qt/debian/copyright deleted file mode 100644 index f7f0d3c..0000000 --- a/src/log4qt/debian/copyright +++ /dev/null @@ -1,45 +0,0 @@ -Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ -Upstream-Name: log4qt -Source: - -Files: * - doc/* - log4qt/* - src/log4qt/* - tests/* -Copyright: 2007 - 2009 Martin Heinrich -License: Apache-2.0 - 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. - . - On Debian systems, the complete text of the Apache License Version 2.0 - can be found in `/usr/share/common-licenses/Apache-2.0'. - -Files: debian/* -Copyright: 2020 Tianjin KYLIN Information Technology Co., Ltd. -License: GPL-3.0+ - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - . - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - . - You should have received a copy of the GNU General Public License - along with this program. If not, see . - . - On Debian systems, the complete text of the GNU General Public License - Version 3 can be found in `/usr/share/common-licenses/GPL-3'. - diff --git a/src/log4qt/debian/libukui-log4qt-dev.install b/src/log4qt/debian/libukui-log4qt-dev.install deleted file mode 100644 index e19765e..0000000 --- a/src/log4qt/debian/libukui-log4qt-dev.install +++ /dev/null @@ -1 +0,0 @@ -ukui-log4qt.h usr/include/ diff --git a/src/log4qt/debian/rules b/src/log4qt/debian/rules deleted file mode 100755 index 52ed6f4..0000000 --- a/src/log4qt/debian/rules +++ /dev/null @@ -1,6 +0,0 @@ -#!/usr/bin/make -f -export QT_SELECT=5 -export DEB_BUILD_MAINT_OPTIONS = hardening=+all - -%: - dh $@ diff --git a/src/log4qt/debian/source/format b/src/log4qt/debian/source/format deleted file mode 100644 index 89ae9db..0000000 --- a/src/log4qt/debian/source/format +++ /dev/null @@ -1 +0,0 @@ -3.0 (native) From 12e394d59fd3d8a3ae2505e8314a0ea6943dbfd9 Mon Sep 17 00:00:00 2001 From: winnerym100 Date: Thu, 15 Jul 2021 17:04:49 +0800 Subject: [PATCH 14/35] fix lintian errors --- data/cn.kylinos.background.service | 2 +- data/cn.kylinos.desktop.service | 2 +- data/cn.kylinos.font.service | 2 +- data/cn.kylinos.interface.service | 2 +- data/cn.kylinos.keyboard.service | 2 +- data/cn.kylinos.marcogeneral.service | 2 +- data/cn.kylinos.mouse.service | 2 +- data/cn.kylinos.power.service | 2 +- data/cn.kylinos.screensaver.service | 2 +- data/cn.kylinos.session.service | 2 +- data/cn.kylinos.touchpad.service | 2 +- data/cn.kylinos.xkbgeneral.service | 2 +- debian/control | 69 +++++++------------ debian/libukui-backgroundclient-dev.install | 1 + debian/libukui-datesetting-dev.install | 1 + debian/libukui-defaultprograms-dev.install | 1 + debian/libukui-desktopclient-dev.install | 1 + debian/libukui-fontclient-dev.install | 1 + debian/libukui-gsettings-dev.install | 1 + debian/libukui-interfaceclient-dev.install | 1 + debian/libukui-keyboardclient-dev.install | 1 + ...og4qt0.install => libukui-log4qt1.install} | 0 ...4qt0.postinst => libukui-log4qt1.postinst} | 0 debian/libukui-marcogeneralclient-dev.install | 1 + debian/libukui-mouseclient-dev.install | 1 + debian/libukui-network-dev.install | 1 + debian/libukui-powerclient-dev.install | 1 + debian/libukui-print-dev.install | 1 + debian/libukui-screensaverclient-dev.install | 1 + debian/libukui-sessionclient-dev.install | 1 + debian/libukui-subversion-dev.install | 1 + debian/libukui-sysinfo-dev.install | 1 + debian/libukui-touchpadclient-dev.install | 1 + debian/libukui-usersetting-dev.install | 1 + debian/libukui-xkbgeneralclient-dev.install | 1 + debian/rules | 7 +- debian/ukui-backgroundserver.install | 2 +- debian/ukui-desktopserver.install | 2 +- debian/ukui-fontserver.install | 2 +- debian/ukui-interfaceserver.install | 2 +- debian/ukui-keyboardserver.install | 2 +- debian/ukui-marcogeneralserver.install | 2 +- debian/ukui-mouseserver.install | 2 +- debian/ukui-powerserver.install | 2 +- debian/ukui-screensaverserver.install | 2 +- debian/ukui-sessionserver.install | 2 +- debian/ukui-touchpadserver.install | 2 +- debian/ukui-xkbgeneralserver.install | 2 +- src/hardware/keyboard/interface-generated.c | 17 ++++- src/hardware/keyboard/interface-generated.h | 17 ++++- src/hardware/keyboard/keyboard-generated.c | 17 ++++- src/hardware/keyboard/keyboard-generated.h | 17 ++++- src/hardware/keyboard/xkbgeneral-generated.c | 17 ++++- src/hardware/keyboard/xkbgeneral-generated.h | 17 ++++- src/hardware/mouse/mouse-generated.c | 17 ++++- src/hardware/mouse/mouse-generated.h | 17 ++++- src/hardware/power/power-generated.c | 17 ++++- src/hardware/power/power-generated.h | 17 ++++- src/hardware/power/screensaver-generated.c | 17 ++++- src/hardware/power/screensaver-generated.h | 17 ++++- src/hardware/power/session-generated.c | 17 ++++- src/hardware/power/session-generated.h | 17 ++++- src/hardware/touchpad/touchpad-generated.c | 17 ++++- src/hardware/touchpad/touchpad-generated.h | 17 ++++- .../background/background-generated.c | 17 ++++- .../background/background-generated.h | 17 ++++- src/personal/desktop/desktop-generated.c | 17 ++++- src/personal/desktop/desktop-generated.h | 17 ++++- src/personal/font/font-generated.c | 17 ++++- src/personal/font/font-generated.h | 17 ++++- .../marcogeneral/marcogeneral-generated.c | 17 ++++- .../marcogeneral/marcogeneral-generated.h | 17 ++++- 72 files changed, 411 insertions(+), 141 deletions(-) rename debian/{libukui-log4qt0.install => libukui-log4qt1.install} (100%) rename debian/{libukui-log4qt0.postinst => libukui-log4qt1.postinst} (100%) diff --git a/data/cn.kylinos.background.service b/data/cn.kylinos.background.service index 1a1ebaa..a150865 100755 --- a/data/cn.kylinos.background.service +++ b/data/cn.kylinos.background.service @@ -1,3 +1,3 @@ [D-BUS Service] Name=cn.kylinos.background -Exec=/usr/lib/ukui-interface/ukui-backgroundserver +Exec=/usr/libexec/ukui-backgroundserver diff --git a/data/cn.kylinos.desktop.service b/data/cn.kylinos.desktop.service index 66d2f6e..08860bf 100755 --- a/data/cn.kylinos.desktop.service +++ b/data/cn.kylinos.desktop.service @@ -1,3 +1,3 @@ [D-BUS Service] Name=cn.kylinos.desktop -Exec=/usr/lib/ukui-interface/ukui-desktopserver +Exec=/usr/libexec/ukui-desktopserver diff --git a/data/cn.kylinos.font.service b/data/cn.kylinos.font.service index 4fd6bae..246ea8c 100755 --- a/data/cn.kylinos.font.service +++ b/data/cn.kylinos.font.service @@ -1,3 +1,3 @@ [D-BUS Service] Name=cn.kylinos.font -Exec=/usr/lib/ukui-interface/ukui-fontserver +Exec=/usr/libexec/ukui-fontserver diff --git a/data/cn.kylinos.interface.service b/data/cn.kylinos.interface.service index dc0579f..c74ddc6 100755 --- a/data/cn.kylinos.interface.service +++ b/data/cn.kylinos.interface.service @@ -1,3 +1,3 @@ [D-BUS Service] Name=cn.kylinos.interface -Exec=/usr/lib/ukui-interface/ukui-interfaceserver +Exec=/usr/libexec/ukui-interfaceserver diff --git a/data/cn.kylinos.keyboard.service b/data/cn.kylinos.keyboard.service index 971535e..f551895 100755 --- a/data/cn.kylinos.keyboard.service +++ b/data/cn.kylinos.keyboard.service @@ -1,3 +1,3 @@ [D-BUS Service] Name=cn.kylinos.keyboard -Exec=/usr/lib/ukui-interface/ukui-keyboardserver +Exec=/usr/libexec/ukui-keyboardserver diff --git a/data/cn.kylinos.marcogeneral.service b/data/cn.kylinos.marcogeneral.service index a0f3d8c..77cf44c 100755 --- a/data/cn.kylinos.marcogeneral.service +++ b/data/cn.kylinos.marcogeneral.service @@ -1,3 +1,3 @@ [D-BUS Service] Name=cn.kylinos.marcogeneral -Exec=/usr/lib/ukui-interface/ukui-marcogeneralserver +Exec=/usr/libexec/ukui-marcogeneralserver diff --git a/data/cn.kylinos.mouse.service b/data/cn.kylinos.mouse.service index 570d43f..9ec364a 100755 --- a/data/cn.kylinos.mouse.service +++ b/data/cn.kylinos.mouse.service @@ -1,3 +1,3 @@ [D-BUS Service] Name=cn.kylinos.mouse -Exec=/usr/lib/ukui-interface/ukui-mouseserver +Exec=/usr/libexec/ukui-mouseserver diff --git a/data/cn.kylinos.power.service b/data/cn.kylinos.power.service index 638ad15..10a373c 100755 --- a/data/cn.kylinos.power.service +++ b/data/cn.kylinos.power.service @@ -1,3 +1,3 @@ [D-BUS Service] Name=cn.kylinos.power -Exec=/usr/lib/ukui-interface/ukui-powerserver +Exec=/usr/libexec/ukui-powerserver diff --git a/data/cn.kylinos.screensaver.service b/data/cn.kylinos.screensaver.service index dbdf2de..99cf141 100755 --- a/data/cn.kylinos.screensaver.service +++ b/data/cn.kylinos.screensaver.service @@ -1,3 +1,3 @@ [D-BUS Service] Name=cn.kylinos.screensaver -Exec=/usr/lib/ukui-interface/ukui-screensaverserver +Exec=/usr/libexec/ukui-screensaverserver diff --git a/data/cn.kylinos.session.service b/data/cn.kylinos.session.service index 622f8a0..51bdbe0 100755 --- a/data/cn.kylinos.session.service +++ b/data/cn.kylinos.session.service @@ -1,3 +1,3 @@ [D-BUS Service] Name=cn.kylinos.session -Exec=/usr/lib/ukui-interface/ukui-sessionserver +Exec=/usr/libexec/ukui-sessionserver diff --git a/data/cn.kylinos.touchpad.service b/data/cn.kylinos.touchpad.service index 3e74e66..50791c2 100755 --- a/data/cn.kylinos.touchpad.service +++ b/data/cn.kylinos.touchpad.service @@ -1,3 +1,3 @@ [D-BUS Service] Name=cn.kylinos.touchpad -Exec=/usr/lib/ukui-interface/ukui-touchpadserver +Exec=/usr/libexec/ukui-touchpadserver diff --git a/data/cn.kylinos.xkbgeneral.service b/data/cn.kylinos.xkbgeneral.service index a2da7e1..571e6cc 100755 --- a/data/cn.kylinos.xkbgeneral.service +++ b/data/cn.kylinos.xkbgeneral.service @@ -1,3 +1,3 @@ [D-BUS Service] Name=cn.kylinos.xkbgeneral -Exec=/usr/lib/ukui-interface/ukui-xkbgeneralserver +Exec=/usr/libexec/ukui-xkbgeneralserver diff --git a/debian/control b/debian/control index aa0c187..b8bb021 100644 --- a/debian/control +++ b/debian/control @@ -29,8 +29,7 @@ Description: print module Package: libukui-print-dev Architecture: any Section: libdevel -Depends: ${shlibs:Depends}, - ${misc:Depends}, +Depends: ${misc:Depends}, libukui-print0 (= ${binary:Version}) Description: print interface UKUI interface provides the interface for system configuration @@ -50,8 +49,7 @@ Description: application settings module Package: libukui-gsettings-dev Architecture: any Section: libdevel -Depends: ${shlibs:Depends}, - ${misc:Depends}, +Depends: ${misc:Depends}, libukui-gsettings0 (= ${binary:Version}) Description: application settings interface UKUI interface provides the interface for system configuration @@ -87,8 +85,7 @@ Description: background settings module Package: libukui-backgroundclient-dev Architecture: any Section: libdevel -Depends: ${shlibs:Depends}, - ${misc:Depends}, +Depends: ${misc:Depends}, libukui-backgroundclient0 (= ${binary:Version}) Description: background settings interfaces UKUI interface provides the interface for system configuration @@ -108,8 +105,7 @@ Description: date settings module Package: libukui-datesetting-dev Architecture: any Section: libdevel -Depends: ${shlibs:Depends}, - ${misc:Depends}, +Depends: ${misc:Depends}, libukui-datesetting0 (= ${binary:Version}) Description: date settings interfaces UKUI interface provides the interface for system configuration @@ -129,8 +125,7 @@ Description: default programs settings module Package: libukui-defaultprograms-dev Architecture: any Section: libdevel -Depends: ${shlibs:Depends}, - ${misc:Depends}, +Depends: ${misc:Depends}, libukui-defaultprograms0 (= ${binary:Version}) Description: default programs settings interfaces UKUI interface provides the interface for system configuration @@ -166,8 +161,7 @@ Description: desktop settings module Package: libukui-desktopclient-dev Architecture: any Section: libdevel -Depends: ${shlibs:Depends}, - ${misc:Depends}, +Depends: ${misc:Depends}, libukui-desktopclient0 (= ${binary:Version}) Description: desktop settings interfaces UKUI interface provides the interface for system configuration @@ -203,8 +197,7 @@ Description: font settings module Package: libukui-fontclient-dev Architecture: any Section: libdevel -Depends: ${shlibs:Depends}, - ${misc:Depends}, +Depends: ${misc:Depends}, libukui-fontclient0 (= ${binary:Version}) Description: font settings interfaces UKUI interface provides the interface for system configuration @@ -240,8 +233,7 @@ Description: interface settings module Package: libukui-interfaceclient-dev Architecture: any Section: libdevel -Depends: ${shlibs:Depends}, - ${misc:Depends}, +Depends: ${misc:Depends}, libukui-interfaceclient0 (= ${binary:Version}) Description: interface settings interfaces UKUI interface provides the interface for system configuration @@ -277,8 +269,7 @@ Description: keyboard settings module Package: libukui-keyboardclient-dev Architecture: any Section: libdevel -Depends: ${shlibs:Depends}, - ${misc:Depends}, +Depends: ${misc:Depends}, libukui-keyboardclient0 (= ${binary:Version}) Description: keyboard settings interfaces UKUI interface provides the interface for system configuration @@ -309,8 +300,7 @@ Description: marcogeneral settings module Package: libukui-marcogeneralclient-dev Architecture: any Section: libdevel -Depends: ${shlibs:Depends}, - ${misc:Depends}, +Depends: ${misc:Depends}, libukui-marcogeneralclient0 (= ${binary:Version}) Description: marcogeneral settings interfaces UKUI interface provides the interface for system configuration @@ -341,8 +331,7 @@ Description: mouse settings module Package: libukui-mouseclient-dev Architecture: any Section: libdevel -Depends: ${shlibs:Depends}, - ${misc:Depends}, +Depends: ${misc:Depends}, libukui-mouseclient0 (= ${binary:Version}) Description: mouse settings interfaces UKUI interface provides the interface for system configuration @@ -362,8 +351,7 @@ Description: network settings module Package: libukui-network-dev Architecture: any Section: libdevel -Depends: ${shlibs:Depends}, - ${misc:Depends}, +Depends: ${misc:Depends}, libukui-network0 (= ${binary:Version}) Description: network settings interfaces UKUI interface provides the interface for system configuration @@ -399,8 +387,7 @@ Description: power settings module Package: libukui-powerclient-dev Architecture: any Section: libdevel -Depends: ${shlibs:Depends}, - ${misc:Depends}, +Depends: ${misc:Depends}, libukui-powerclient0 (= ${binary:Version}) Description: power settings interfaces UKUI interface provides the interface for system configuration @@ -431,8 +418,7 @@ Description: screensaver settings module Package: libukui-screensaverclient-dev Architecture: any Section: libdevel -Depends: ${shlibs:Depends}, - ${misc:Depends}, +Depends: ${misc:Depends}, libukui-screensaverclient0 (= ${binary:Version}) Description: screensaver settings interfaces UKUI interface provides the interface for system configuration @@ -463,8 +449,7 @@ Description: session settings module Package: libukui-sessionclient-dev Architecture: any Section: libdevel -Depends: ${shlibs:Depends}, - ${misc:Depends}, +Depends: ${misc:Depends}, libukui-sessionclient0 (= ${binary:Version}) Description: session settings interfaces UKUI interface provides the interface for system configuration @@ -484,8 +469,7 @@ Description: Subversion check module Package: libukui-subversion-dev Architecture: any Section: libdevel -Depends: ${shlibs:Depends}, - ${misc:Depends}, +Depends: ${misc:Depends}, libukui-subversion0 (= ${binary:Version}) Description: Subversion check interfaces UKUI interface provides the interface for system configuration @@ -505,8 +489,7 @@ Description: system information gettings module Package: libukui-sysinfo-dev Architecture: any Section: libdevel -Depends: ${shlibs:Depends}, - ${misc:Depends}, +Depends: ${misc:Depends}, libukui-sysinfo0 (= ${binary:Version}) Description: system information gettings interfaces UKUI interface provides the interface for system configuration @@ -542,8 +525,7 @@ Description: touchpad settings module Package: libukui-touchpadclient-dev Architecture: any Section: libdevel -Depends: ${shlibs:Depends}, - ${misc:Depends}, +Depends: ${misc:Depends}, libukui-touchpadclient0 (= ${binary:Version}) Description: touchpad settings interfaces UKUI interface provides the interface for system configuration @@ -563,8 +545,7 @@ Description: user settings module Package: libukui-usersetting-dev Architecture: any Section: libdevel -Depends: ${shlibs:Depends}, - ${misc:Depends}, +Depends: ${misc:Depends}, libukui-usersetting0 (= ${binary:Version}) Description: user settings interfaces UKUI interface provides the interface for system configuration @@ -595,8 +576,7 @@ Description: xkbgeneral settings module Package: libukui-xkbgeneralclient-dev Architecture: any Section: libdevel -Depends: ${shlibs:Depends}, - ${misc:Depends}, +Depends: ${misc:Depends}, libukui-xkbgeneralclient0 (= ${binary:Version}) Description: xkbgeneral settings interfaces UKUI interface provides the interface for system configuration @@ -604,9 +584,11 @@ Description: xkbgeneral settings interfaces . The package contains development files for xkbgeneral settings. -Package: libukui-log4qt0 +Package: libukui-log4qt1 Architecture: any Depends: ${shlibs:Depends}, ${misc:Depends}, libglib2.0-bin +Suggests: libukui-log4qt0 +Replaces: libukui-log4qt0 Description: log4qt module UKUI interface provides the interface for system configuration and related libraries. @@ -616,9 +598,8 @@ Description: log4qt module Package: libukui-log4qt-dev Architecture: any Section: libdevel -Depends: ${shlibs:Depends}, - ${misc:Depends}, - libukui-log4qt0 (= ${binary:Version}), +Depends: ${misc:Depends}, + libukui-log4qt1 (= ${binary:Version}), libglib2.0-bin Description: log4qt interface UKUI interface provides the interface for system configuration diff --git a/debian/libukui-backgroundclient-dev.install b/debian/libukui-backgroundclient-dev.install index 2ce7946..5ef2cec 100644 --- a/debian/libukui-backgroundclient-dev.install +++ b/debian/libukui-backgroundclient-dev.install @@ -1,3 +1,4 @@ usr/include/ukuisdk/kylin-background-interface.h usr/lib/*/libukui-backgroundclient.a +usr/lib/*/libukui-backgroundclient.la usr/lib/*/libukui-backgroundclient.so diff --git a/debian/libukui-datesetting-dev.install b/debian/libukui-datesetting-dev.install index 5d5057d..c4da7ef 100644 --- a/debian/libukui-datesetting-dev.install +++ b/debian/libukui-datesetting-dev.install @@ -1,3 +1,4 @@ usr/include/ukuisdk/kylin-date-interface.h usr/lib/*/libukui-datesetting.a +usr/lib/*/libukui-datesetting.la usr/lib/*/libukui-datesetting.so diff --git a/debian/libukui-defaultprograms-dev.install b/debian/libukui-defaultprograms-dev.install index fa46493..6bf524b 100644 --- a/debian/libukui-defaultprograms-dev.install +++ b/debian/libukui-defaultprograms-dev.install @@ -1,3 +1,4 @@ usr/include/ukuisdk/kylin-defaultprograms-interface.h usr/lib/*/libukui-defaultprograms.a +usr/lib/*/libukui-defaultprograms.la usr/lib/*/libukui-defaultprograms.so diff --git a/debian/libukui-desktopclient-dev.install b/debian/libukui-desktopclient-dev.install index c3a29df..3fcbe56 100644 --- a/debian/libukui-desktopclient-dev.install +++ b/debian/libukui-desktopclient-dev.install @@ -1,3 +1,4 @@ usr/include/ukuisdk/kylin-desktop-interface.h usr/lib/*/libukui-desktopclient.a +usr/lib/*/libukui-desktopclient.la usr/lib/*/libukui-desktopclient.so diff --git a/debian/libukui-fontclient-dev.install b/debian/libukui-fontclient-dev.install index 2ed144f..48e0d81 100644 --- a/debian/libukui-fontclient-dev.install +++ b/debian/libukui-fontclient-dev.install @@ -1,3 +1,4 @@ usr/include/ukuisdk/kylin-font-interface.h usr/lib/*/libukui-fontclient.a +usr/lib/*/libukui-fontclient.la usr/lib/*/libukui-fontclient.so diff --git a/debian/libukui-gsettings-dev.install b/debian/libukui-gsettings-dev.install index 08dec84..ac6498e 100644 --- a/debian/libukui-gsettings-dev.install +++ b/debian/libukui-gsettings-dev.install @@ -1,3 +1,4 @@ usr/include/ukuisdk/kylin-gsettings-set.h usr/lib/*/libukui-gsettings.a +usr/lib/*/libukui-gsettings.la usr/lib/*/libukui-gsettings.so diff --git a/debian/libukui-interfaceclient-dev.install b/debian/libukui-interfaceclient-dev.install index 4ecacba..03aff39 100644 --- a/debian/libukui-interfaceclient-dev.install +++ b/debian/libukui-interfaceclient-dev.install @@ -1,3 +1,4 @@ usr/include/ukuisdk/kylin-interface-interface.h usr/lib/*/libukui-interfaceclient.a +usr/lib/*/libukui-interfaceclient.la usr/lib/*/libukui-interfaceclient.so diff --git a/debian/libukui-keyboardclient-dev.install b/debian/libukui-keyboardclient-dev.install index 4a9203c..4003aea 100644 --- a/debian/libukui-keyboardclient-dev.install +++ b/debian/libukui-keyboardclient-dev.install @@ -1,3 +1,4 @@ usr/include/ukuisdk/kylin-keyboard-interface.h usr/lib/*/libukui-keyboardclient.a +usr/lib/*/libukui-keyboardclient.la usr/lib/*/libukui-keyboardclient.so diff --git a/debian/libukui-log4qt0.install b/debian/libukui-log4qt1.install similarity index 100% rename from debian/libukui-log4qt0.install rename to debian/libukui-log4qt1.install diff --git a/debian/libukui-log4qt0.postinst b/debian/libukui-log4qt1.postinst similarity index 100% rename from debian/libukui-log4qt0.postinst rename to debian/libukui-log4qt1.postinst diff --git a/debian/libukui-marcogeneralclient-dev.install b/debian/libukui-marcogeneralclient-dev.install index 3f1c68a..f578da2 100644 --- a/debian/libukui-marcogeneralclient-dev.install +++ b/debian/libukui-marcogeneralclient-dev.install @@ -1,3 +1,4 @@ usr/include/ukuisdk/kylin-marcogeneral-interface.h usr/lib/*/libukui-marcogeneralclient.a +usr/lib/*/libukui-marcogeneralclient.la usr/lib/*/libukui-marcogeneralclient.so diff --git a/debian/libukui-mouseclient-dev.install b/debian/libukui-mouseclient-dev.install index cdda61c..d27b0ef 100644 --- a/debian/libukui-mouseclient-dev.install +++ b/debian/libukui-mouseclient-dev.install @@ -1,3 +1,4 @@ usr/include/ukuisdk/kylin-mouse-interface.h usr/lib/*/libukui-mouseclient.a +usr/lib/*/libukui-mouseclient.la usr/lib/*/libukui-mouseclient.so diff --git a/debian/libukui-network-dev.install b/debian/libukui-network-dev.install index 019c694..d4e9890 100644 --- a/debian/libukui-network-dev.install +++ b/debian/libukui-network-dev.install @@ -1,3 +1,4 @@ usr/include/ukuisdk/kylin-network-interface.h usr/lib/*/libukui-network.a +usr/lib/*/libukui-network.la usr/lib/*/libukui-network.so diff --git a/debian/libukui-powerclient-dev.install b/debian/libukui-powerclient-dev.install index bc9ec08..f7e4726 100644 --- a/debian/libukui-powerclient-dev.install +++ b/debian/libukui-powerclient-dev.install @@ -1,3 +1,4 @@ usr/include/ukuisdk/kylin-power-interface.h usr/lib/*/libukui-powerclient.a +usr/lib/*/libukui-powerclient.la usr/lib/*/libukui-powerclient.so diff --git a/debian/libukui-print-dev.install b/debian/libukui-print-dev.install index dba095a..19462df 100644 --- a/debian/libukui-print-dev.install +++ b/debian/libukui-print-dev.install @@ -1,3 +1,4 @@ usr/include/ukuisdk/kylin-print.h usr/lib/*/libukui-print.a +usr/lib/*/libukui-print.la usr/lib/*/libukui-print.so diff --git a/debian/libukui-screensaverclient-dev.install b/debian/libukui-screensaverclient-dev.install index ca2a445..d5b667d 100644 --- a/debian/libukui-screensaverclient-dev.install +++ b/debian/libukui-screensaverclient-dev.install @@ -1,3 +1,4 @@ usr/include/ukuisdk/kylin-screensaver-interface.h usr/lib/*/libukui-screensaverclient.a +usr/lib/*/libukui-screensaverclient.la usr/lib/*/libukui-screensaverclient.so diff --git a/debian/libukui-sessionclient-dev.install b/debian/libukui-sessionclient-dev.install index 7613c06..232a76c 100644 --- a/debian/libukui-sessionclient-dev.install +++ b/debian/libukui-sessionclient-dev.install @@ -1,3 +1,4 @@ usr/include/ukuisdk/kylin-session-interface.h usr/lib/*/libukui-sessionclient.a +usr/lib/*/libukui-sessionclient.la usr/lib/*/libukui-sessionclient.so diff --git a/debian/libukui-subversion-dev.install b/debian/libukui-subversion-dev.install index fbdb01f..ed42bee 100644 --- a/debian/libukui-subversion-dev.install +++ b/debian/libukui-subversion-dev.install @@ -1,3 +1,4 @@ usr/include/ukuisdk/kylin-version-interface.h usr/lib/*/libukui-subversion.a +usr/lib/*/libukui-subversion.la usr/lib/*/libukui-subversion.so diff --git a/debian/libukui-sysinfo-dev.install b/debian/libukui-sysinfo-dev.install index fd82601..0372ccd 100644 --- a/debian/libukui-sysinfo-dev.install +++ b/debian/libukui-sysinfo-dev.install @@ -1,3 +1,4 @@ usr/include/ukuisdk/kylin-sysinfo-interface.h usr/lib/*/libukui-sysinfo.a +usr/lib/*/libukui-sysinfo.la usr/lib/*/libukui-sysinfo.so diff --git a/debian/libukui-touchpadclient-dev.install b/debian/libukui-touchpadclient-dev.install index 7f0ecd9..4da0d7d 100644 --- a/debian/libukui-touchpadclient-dev.install +++ b/debian/libukui-touchpadclient-dev.install @@ -1,3 +1,4 @@ usr/include/ukuisdk/kylin-touchpad-interface.h usr/lib/*/libukui-touchpadclient.a +usr/lib/*/libukui-touchpadclient.la usr/lib/*/libukui-touchpadclient.so diff --git a/debian/libukui-usersetting-dev.install b/debian/libukui-usersetting-dev.install index 14913df..17473c3 100644 --- a/debian/libukui-usersetting-dev.install +++ b/debian/libukui-usersetting-dev.install @@ -1,3 +1,4 @@ usr/include/ukuisdk/kylin-user-interface.h usr/lib/*/libukui-usersetting.a +usr/lib/*/libukui-usersetting.la usr/lib/*/libukui-usersetting.so diff --git a/debian/libukui-xkbgeneralclient-dev.install b/debian/libukui-xkbgeneralclient-dev.install index 24951c1..3154d18 100644 --- a/debian/libukui-xkbgeneralclient-dev.install +++ b/debian/libukui-xkbgeneralclient-dev.install @@ -1,3 +1,4 @@ usr/include/ukuisdk/kylin-xkbgeneral-interface.h usr/lib/*/libukui-xkbgeneralclient.a +usr/lib/*/libukui-xkbgeneralclient.la usr/lib/*/libukui-xkbgeneralclient.so diff --git a/debian/rules b/debian/rules index e68d54d..deb2418 100755 --- a/debian/rules +++ b/debian/rules @@ -8,6 +8,10 @@ export DEB_BUILD_MAINT_OPTIONS = hardening=+all #export DEB_LDFLAGS_MAINT_APPEND = -Wl,--as-needed QT_INSTALL_DIR:=$(shell pwd)/debian/tmp/ LOG4QT_BUILD_DIR:=$(shell pwd)/src/log4qt/build +CPPFLAGS:=$(shell dpkg-buildflags --get CPPFLAGS) +CFLAGS:=$(shell dpkg-buildflags --get CFLAGS) $(CPPFLAGS) +CXXFLAGS:=$(shell dpkg-buildflags --get CXXFLAGS) $(CPPFLAGS) +LDFLAGS:=$(shell dpkg-buildflags --get LDFLAGS) %: dh $@ @@ -20,11 +24,12 @@ override_dh_install: mkdir -p $(QT_INSTALL_DIR) && \ make install INSTALL_ROOT=$(QT_INSTALL_DIR) -C $(LOG4QT_BUILD_DIR) dh_install + sed -i "/dependency_libs/ s/'.*'/''/" `find . -name '*.la'` override_dh_auto_configure: ./autogen.sh dh_auto_configure -- \ - --includedir=/usr/include/ukuisdk --bindir=/usr/lib/ukui-interface + --includedir=/usr/include/ukuisdk --bindir=/usr/libexec override_dh_auto_build: dh_auto_build diff --git a/debian/ukui-backgroundserver.install b/debian/ukui-backgroundserver.install index 5fb4052..eb516be 100644 --- a/debian/ukui-backgroundserver.install +++ b/debian/ukui-backgroundserver.install @@ -1,2 +1,2 @@ -usr/lib/ukui-interface/ukui-backgroundserver +usr/libexec/ukui-backgroundserver usr/share/dbus-1/services/cn.kylinos.background.service diff --git a/debian/ukui-desktopserver.install b/debian/ukui-desktopserver.install index 5751421..c4db8fa 100644 --- a/debian/ukui-desktopserver.install +++ b/debian/ukui-desktopserver.install @@ -1,2 +1,2 @@ -usr/lib/ukui-interface/ukui-desktopserver +usr/libexec/ukui-desktopserver usr/share/dbus-1/services/cn.kylinos.desktop.service diff --git a/debian/ukui-fontserver.install b/debian/ukui-fontserver.install index c7c12bf..89e2666 100644 --- a/debian/ukui-fontserver.install +++ b/debian/ukui-fontserver.install @@ -1,2 +1,2 @@ -usr/lib/ukui-interface/ukui-fontserver +usr/libexec/ukui-fontserver usr/share/dbus-1/services/cn.kylinos.font.service diff --git a/debian/ukui-interfaceserver.install b/debian/ukui-interfaceserver.install index dbc0c2c..c3852b1 100644 --- a/debian/ukui-interfaceserver.install +++ b/debian/ukui-interfaceserver.install @@ -1,2 +1,2 @@ -usr/lib/ukui-interface/ukui-interfaceserver +usr/libexec/ukui-interfaceserver usr/share/dbus-1/services/cn.kylinos.interface.service diff --git a/debian/ukui-keyboardserver.install b/debian/ukui-keyboardserver.install index 436f114..3eec720 100644 --- a/debian/ukui-keyboardserver.install +++ b/debian/ukui-keyboardserver.install @@ -1,2 +1,2 @@ -usr/lib/ukui-interface/ukui-keyboardserver +usr/libexec/ukui-keyboardserver usr/share/dbus-1/services/cn.kylinos.keyboard.service diff --git a/debian/ukui-marcogeneralserver.install b/debian/ukui-marcogeneralserver.install index 123d8b1..434e477 100644 --- a/debian/ukui-marcogeneralserver.install +++ b/debian/ukui-marcogeneralserver.install @@ -1,2 +1,2 @@ -usr/lib/ukui-interface/ukui-marcogeneralserver +usr/libexec/ukui-marcogeneralserver usr/share/dbus-1/services/cn.kylinos.marcogeneral.service diff --git a/debian/ukui-mouseserver.install b/debian/ukui-mouseserver.install index 049cbf0..393a548 100644 --- a/debian/ukui-mouseserver.install +++ b/debian/ukui-mouseserver.install @@ -1,2 +1,2 @@ -usr/lib/ukui-interface/ukui-mouseserver +usr/libexec/ukui-mouseserver usr/share/dbus-1/services/cn.kylinos.mouse.service diff --git a/debian/ukui-powerserver.install b/debian/ukui-powerserver.install index c4ce14b..c9143aa 100644 --- a/debian/ukui-powerserver.install +++ b/debian/ukui-powerserver.install @@ -1,2 +1,2 @@ -usr/lib/ukui-interface/ukui-powerserver +usr/libexec/ukui-powerserver usr/share/dbus-1/services/cn.kylinos.power.service diff --git a/debian/ukui-screensaverserver.install b/debian/ukui-screensaverserver.install index 4e7647e..aabc00c 100644 --- a/debian/ukui-screensaverserver.install +++ b/debian/ukui-screensaverserver.install @@ -1,2 +1,2 @@ -usr/lib/ukui-interface/ukui-screensaverserver +usr/libexec/ukui-screensaverserver usr/share/dbus-1/services/cn.kylinos.screensaver.service diff --git a/debian/ukui-sessionserver.install b/debian/ukui-sessionserver.install index 236d475..40be13b 100644 --- a/debian/ukui-sessionserver.install +++ b/debian/ukui-sessionserver.install @@ -1,2 +1,2 @@ -usr/lib/ukui-interface/ukui-sessionserver +usr/libexec/ukui-sessionserver usr/share/dbus-1/services/cn.kylinos.session.service diff --git a/debian/ukui-touchpadserver.install b/debian/ukui-touchpadserver.install index 612b8d4..8c5588c 100644 --- a/debian/ukui-touchpadserver.install +++ b/debian/ukui-touchpadserver.install @@ -1,2 +1,2 @@ -usr/lib/ukui-interface/ukui-touchpadserver +usr/libexec/ukui-touchpadserver usr/share/dbus-1/services/cn.kylinos.touchpad.service diff --git a/debian/ukui-xkbgeneralserver.install b/debian/ukui-xkbgeneralserver.install index df2dd09..0e08e5a 100644 --- a/debian/ukui-xkbgeneralserver.install +++ b/debian/ukui-xkbgeneralserver.install @@ -1,2 +1,2 @@ -usr/lib/ukui-interface/ukui-xkbgeneralserver +usr/libexec/ukui-xkbgeneralserver usr/share/dbus-1/services/cn.kylinos.xkbgeneral.service diff --git a/src/hardware/keyboard/interface-generated.c b/src/hardware/keyboard/interface-generated.c index 2e1d8bd..0ad29d5 100644 --- a/src/hardware/keyboard/interface-generated.c +++ b/src/hardware/keyboard/interface-generated.c @@ -1,8 +1,19 @@ /* - * Generated by gdbus-codegen 2.62.4 from cn.kylinos.interface.xml. DO NOT EDIT. + * Copyright (C) 2019 Tianjin KYLIN Information Technology Co., Ltd. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see Date: Fri, 16 Jul 2021 16:41:17 +0800 Subject: [PATCH 15/35] fix lintian error --- debian/control | 102 -------------------- debian/libukui-datesetting-dev.install | 4 - debian/libukui-datesetting0.install | 1 - debian/libukui-datesetting0.symbols | 8 -- debian/libukui-defaultprograms-dev.install | 4 - debian/libukui-defaultprograms0.install | 1 - debian/libukui-defaultprograms0.symbols | 14 --- debian/libukui-subversion-dev.install | 4 - debian/libukui-subversion0.install | 1 - debian/libukui-subversion0.symbols | 12 --- debian/libukui-sysinfo-dev.install | 4 - debian/libukui-sysinfo0.install | 1 - debian/libukui-sysinfo0.symbols | 7 -- debian/libukui-xkbgeneralclient-dev.install | 4 - debian/libukui-xkbgeneralclient0.install | 1 - debian/libukui-xkbgeneralclient0.symbols | 28 ------ debian/rules | 4 - debian/tests/control | 3 + debian/tests/testlog4qt.sh | 5 + src/Makefile.am | 4 +- src/hardware/keyboard/Makefile.am | 24 +---- 21 files changed, 14 insertions(+), 222 deletions(-) delete mode 100644 debian/libukui-datesetting-dev.install delete mode 100644 debian/libukui-datesetting0.install delete mode 100644 debian/libukui-datesetting0.symbols delete mode 100644 debian/libukui-defaultprograms-dev.install delete mode 100644 debian/libukui-defaultprograms0.install delete mode 100644 debian/libukui-defaultprograms0.symbols delete mode 100644 debian/libukui-subversion-dev.install delete mode 100644 debian/libukui-subversion0.install delete mode 100644 debian/libukui-subversion0.symbols delete mode 100644 debian/libukui-sysinfo-dev.install delete mode 100644 debian/libukui-sysinfo0.install delete mode 100644 debian/libukui-sysinfo0.symbols delete mode 100644 debian/libukui-xkbgeneralclient-dev.install delete mode 100644 debian/libukui-xkbgeneralclient0.install delete mode 100644 debian/libukui-xkbgeneralclient0.symbols create mode 100644 debian/tests/control create mode 100755 debian/tests/testlog4qt.sh diff --git a/debian/control b/debian/control index b8bb021..93d6a14 100644 --- a/debian/control +++ b/debian/control @@ -93,46 +93,6 @@ Description: background settings interfaces . The package contains development files for background settings. -Package: libukui-datesetting0 -Architecture: any -Depends: ${shlibs:Depends}, ${misc:Depends} -Description: date settings module - UKUI interface provides the interface for system configuration - and related libraries. - . - The package contains date settings libraries. - -Package: libukui-datesetting-dev -Architecture: any -Section: libdevel -Depends: ${misc:Depends}, - libukui-datesetting0 (= ${binary:Version}) -Description: date settings interfaces - UKUI interface provides the interface for system configuration - and related libraries. - . - The package contains development files for date settings. - -Package: libukui-defaultprograms0 -Architecture: any -Depends: ${shlibs:Depends}, ${misc:Depends} -Description: default programs settings module - UKUI interface provides the interface for system configuration - and related libraries. - . - The package contains default programs settings libraries. - -Package: libukui-defaultprograms-dev -Architecture: any -Section: libdevel -Depends: ${misc:Depends}, - libukui-defaultprograms0 (= ${binary:Version}) -Description: default programs settings interfaces - UKUI interface provides the interface for system configuration - and related libraries. - . - The package contains development files for default programs settings. - Package: ukui-desktopserver Architecture: any Depends: ${shlibs:Depends}, @@ -457,46 +417,6 @@ Description: session settings interfaces . The package contains development files for session settings. -Package: libukui-subversion0 -Architecture: any -Depends: ${shlibs:Depends}, ${misc:Depends} -Description: Subversion check module - UKUI interface provides the interface for system configuration - and related libraries. - . - The package contains Subversion check libraries. - -Package: libukui-subversion-dev -Architecture: any -Section: libdevel -Depends: ${misc:Depends}, - libukui-subversion0 (= ${binary:Version}) -Description: Subversion check interfaces - UKUI interface provides the interface for system configuration - and related libraries. - . - The package contains development files for Subversion check. - -Package: libukui-sysinfo0 -Architecture: any -Depends: ${shlibs:Depends}, ${misc:Depends} -Description: system information gettings module - UKUI interface provides the interface for system configuration - and related libraries. - . - The package contains system information gettings libraries. - -Package: libukui-sysinfo-dev -Architecture: any -Section: libdevel -Depends: ${misc:Depends}, - libukui-sysinfo0 (= ${binary:Version}) -Description: system information gettings interfaces - UKUI interface provides the interface for system configuration - and related libraries. - . - The package contains development files for system information gettings. - Package: ukui-touchpadserver Architecture: any Depends: ${shlibs:Depends}, @@ -562,28 +482,6 @@ Description: xkbgeneral settings service process . The package contains xkbgeneral settings service process. -Package: libukui-xkbgeneralclient0 -Architecture: any -Depends: ${shlibs:Depends}, - ${misc:Depends}, - ukui-xkbgeneralserver (= ${binary:Version}) -Description: xkbgeneral settings module - UKUI interface provides the interface for system configuration - and related libraries. - . - The package contains xkbgeneral settings libraries. - -Package: libukui-xkbgeneralclient-dev -Architecture: any -Section: libdevel -Depends: ${misc:Depends}, - libukui-xkbgeneralclient0 (= ${binary:Version}) -Description: xkbgeneral settings interfaces - UKUI interface provides the interface for system configuration - and related libraries. - . - The package contains development files for xkbgeneral settings. - Package: libukui-log4qt1 Architecture: any Depends: ${shlibs:Depends}, ${misc:Depends}, libglib2.0-bin diff --git a/debian/libukui-datesetting-dev.install b/debian/libukui-datesetting-dev.install deleted file mode 100644 index c4da7ef..0000000 --- a/debian/libukui-datesetting-dev.install +++ /dev/null @@ -1,4 +0,0 @@ -usr/include/ukuisdk/kylin-date-interface.h -usr/lib/*/libukui-datesetting.a -usr/lib/*/libukui-datesetting.la -usr/lib/*/libukui-datesetting.so diff --git a/debian/libukui-datesetting0.install b/debian/libukui-datesetting0.install deleted file mode 100644 index 21bc83e..0000000 --- a/debian/libukui-datesetting0.install +++ /dev/null @@ -1 +0,0 @@ -usr/lib/*/libukui-datesetting.so.* diff --git a/debian/libukui-datesetting0.symbols b/debian/libukui-datesetting0.symbols deleted file mode 100644 index 7b53e0b..0000000 --- a/debian/libukui-datesetting0.symbols +++ /dev/null @@ -1,8 +0,0 @@ -libukui-datesetting.so.0 libukui-datesetting0 #MINVER# -* Build-Depends-Package: libukui-datesetting-dev - init_timedb@Base 1.0.0 - kylin_date_dt_chgdt@Base 1.0.0 - kylin_date_dt_sethrfmt@Base 1.0.0 - kylin_date_dt_setnetsync@Base 1.0.0 - kylin_date_dt_settz@Base 1.0.0 - timedata@Base 1.0.0 diff --git a/debian/libukui-defaultprograms-dev.install b/debian/libukui-defaultprograms-dev.install deleted file mode 100644 index 6bf524b..0000000 --- a/debian/libukui-defaultprograms-dev.install +++ /dev/null @@ -1,4 +0,0 @@ -usr/include/ukuisdk/kylin-defaultprograms-interface.h -usr/lib/*/libukui-defaultprograms.a -usr/lib/*/libukui-defaultprograms.la -usr/lib/*/libukui-defaultprograms.so diff --git a/debian/libukui-defaultprograms0.install b/debian/libukui-defaultprograms0.install deleted file mode 100644 index b67107e..0000000 --- a/debian/libukui-defaultprograms0.install +++ /dev/null @@ -1 +0,0 @@ -usr/lib/*/libukui-defaultprograms.so.* diff --git a/debian/libukui-defaultprograms0.symbols b/debian/libukui-defaultprograms0.symbols deleted file mode 100644 index 020cf76..0000000 --- a/debian/libukui-defaultprograms0.symbols +++ /dev/null @@ -1,14 +0,0 @@ -libukui-defaultprograms.so.0 libukui-defaultprograms0 #MINVER# -* Build-Depends-Package: libukui-defaultprograms-dev - kylin_software_defaultprograms_addapptype@Base 1.0.0 - kylin_software_defaultprograms_delapptype@Base 1.0.0 - kylin_software_defaultprograms_getappcontenttype@Base 1.0.0 - kylin_software_defaultprograms_getappidlist@Base 1.0.0 - kylin_software_defaultprograms_getdefaultappid@Base 1.0.0 - kylin_software_defaultprograms_setaudioplayers@Base 1.0.0 - kylin_software_defaultprograms_setdefaultapp@Base 1.0.0 - kylin_software_defaultprograms_setimageviewers@Base 1.0.0 - kylin_software_defaultprograms_setmailreaders@Base 1.0.0 - kylin_software_defaultprograms_settexteditors@Base 1.0.0 - kylin_software_defaultprograms_setvideoplayers@Base 1.0.0 - kylin_software_defaultprograms_setwebbrowsers@Base 1.0.0 diff --git a/debian/libukui-subversion-dev.install b/debian/libukui-subversion-dev.install deleted file mode 100644 index ed42bee..0000000 --- a/debian/libukui-subversion-dev.install +++ /dev/null @@ -1,4 +0,0 @@ -usr/include/ukuisdk/kylin-version-interface.h -usr/lib/*/libukui-subversion.a -usr/lib/*/libukui-subversion.la -usr/lib/*/libukui-subversion.so diff --git a/debian/libukui-subversion0.install b/debian/libukui-subversion0.install deleted file mode 100644 index c1c9b4b..0000000 --- a/debian/libukui-subversion0.install +++ /dev/null @@ -1 +0,0 @@ -usr/lib/*/libukui-subversion.so.* diff --git a/debian/libukui-subversion0.symbols b/debian/libukui-subversion0.symbols deleted file mode 100644 index 397880f..0000000 --- a/debian/libukui-subversion0.symbols +++ /dev/null @@ -1,12 +0,0 @@ -libukui-subversion.so.0 libukui-subversion0 #MINVER# -* Build-Depends-Package: libukui-subversion-dev - _Z10searchFilePKc@Base 1.0.0 - _Z6cmpKeyPKc@Base 1.0.0 - _ZN10QByteArrayD1Ev@Base 1.0.0 - _ZN10QByteArrayD2Ev@Base 1.0.0 - _ZN5QListI7QStringED1Ev@Base 1.0.0 - _ZN5QListI7QStringED2Ev@Base 1.0.0 - _ZN7QStringD1Ev@Base 1.0.0 - _ZN7QStringD2Ev@Base 1.0.0 - kylin_os_sysinfo_getchildrroup@Base 1.0.0 - kylin_os_sysinfo_verifysubversion@Base 1.0.0 diff --git a/debian/libukui-sysinfo-dev.install b/debian/libukui-sysinfo-dev.install deleted file mode 100644 index 0372ccd..0000000 --- a/debian/libukui-sysinfo-dev.install +++ /dev/null @@ -1,4 +0,0 @@ -usr/include/ukuisdk/kylin-sysinfo-interface.h -usr/lib/*/libukui-sysinfo.a -usr/lib/*/libukui-sysinfo.la -usr/lib/*/libukui-sysinfo.so diff --git a/debian/libukui-sysinfo0.install b/debian/libukui-sysinfo0.install deleted file mode 100644 index 285ee0a..0000000 --- a/debian/libukui-sysinfo0.install +++ /dev/null @@ -1 +0,0 @@ -usr/lib/*/libukui-sysinfo.so.* diff --git a/debian/libukui-sysinfo0.symbols b/debian/libukui-sysinfo0.symbols deleted file mode 100644 index 7784c06..0000000 --- a/debian/libukui-sysinfo0.symbols +++ /dev/null @@ -1,7 +0,0 @@ -libukui-sysinfo.so.0 libukui-sysinfo0 #MINVER# -* Build-Depends-Package: libukui-sysinfo-dev - kylin_os_sysinfo_machine@Base 1.0.0 - kylin_os_sysinfo_nodename@Base 1.0.0 - kylin_os_sysinfo_release@Base 1.0.0 - kylin_os_sysinfo_sysname@Base 1.0.0 - kylin_os_sysinfo_version@Base 1.0.0 diff --git a/debian/libukui-xkbgeneralclient-dev.install b/debian/libukui-xkbgeneralclient-dev.install deleted file mode 100644 index 3154d18..0000000 --- a/debian/libukui-xkbgeneralclient-dev.install +++ /dev/null @@ -1,4 +0,0 @@ -usr/include/ukuisdk/kylin-xkbgeneral-interface.h -usr/lib/*/libukui-xkbgeneralclient.a -usr/lib/*/libukui-xkbgeneralclient.la -usr/lib/*/libukui-xkbgeneralclient.so diff --git a/debian/libukui-xkbgeneralclient0.install b/debian/libukui-xkbgeneralclient0.install deleted file mode 100644 index 1fb506c..0000000 --- a/debian/libukui-xkbgeneralclient0.install +++ /dev/null @@ -1 +0,0 @@ -usr/lib/*/libukui-xkbgeneralclient.so.* diff --git a/debian/libukui-xkbgeneralclient0.symbols b/debian/libukui-xkbgeneralclient0.symbols deleted file mode 100644 index e58583f..0000000 --- a/debian/libukui-xkbgeneralclient0.symbols +++ /dev/null @@ -1,28 +0,0 @@ -libukui-xkbgeneralclient.so.0 libukui-xkbgeneralclient0 #MINVER# -* Build-Depends-Package: libukui-xkbgeneralclient-dev - DeInitDBusXkbgeneral@Base 1.0.0 - InitDBusXkbgeneral@Base 1.0.0 - kylin_hardware_keyboard_get_groupperwindow@Base 1.0.0 - kylin_hardware_keyboard_set_groupperwindow@Base 1.0.0 - run@Base 1.0.0 - thread_create@Base 1.0.0 - xkbgeneral_call_get_bool_value@Base 1.0.0 - xkbgeneral_call_get_bool_value_finish@Base 1.0.0 - xkbgeneral_call_get_bool_value_sync@Base 1.0.0 - xkbgeneral_call_transfer_bool_value@Base 1.0.0 - xkbgeneral_call_transfer_bool_value_finish@Base 1.0.0 - xkbgeneral_call_transfer_bool_value_sync@Base 1.0.0 - xkbgeneral_complete_get_bool_value@Base 1.0.0 - xkbgeneral_complete_transfer_bool_value@Base 1.0.0 - xkbgeneral_get_type@Base 1.0.0 - xkbgeneral_interface_info@Base 1.0.0 - xkbgeneral_override_properties@Base 1.0.0 - xkbgeneral_proxy_get_type@Base 1.0.0 - xkbgeneral_proxy_new@Base 1.0.0 - xkbgeneral_proxy_new_finish@Base 1.0.0 - xkbgeneral_proxy_new_for_bus@Base 1.0.0 - xkbgeneral_proxy_new_for_bus_finish@Base 1.0.0 - xkbgeneral_proxy_new_for_bus_sync@Base 1.0.0 - xkbgeneral_proxy_new_sync@Base 1.0.0 - xkbgeneral_skeleton_get_type@Base 1.0.0 - xkbgeneral_skeleton_new@Base 1.0.0 diff --git a/debian/rules b/debian/rules index deb2418..c32bfa0 100755 --- a/debian/rules +++ b/debian/rules @@ -8,10 +8,6 @@ export DEB_BUILD_MAINT_OPTIONS = hardening=+all #export DEB_LDFLAGS_MAINT_APPEND = -Wl,--as-needed QT_INSTALL_DIR:=$(shell pwd)/debian/tmp/ LOG4QT_BUILD_DIR:=$(shell pwd)/src/log4qt/build -CPPFLAGS:=$(shell dpkg-buildflags --get CPPFLAGS) -CFLAGS:=$(shell dpkg-buildflags --get CFLAGS) $(CPPFLAGS) -CXXFLAGS:=$(shell dpkg-buildflags --get CXXFLAGS) $(CPPFLAGS) -LDFLAGS:=$(shell dpkg-buildflags --get LDFLAGS) %: dh $@ diff --git a/debian/tests/control b/debian/tests/control new file mode 100644 index 0000000..d035d06 --- /dev/null +++ b/debian/tests/control @@ -0,0 +1,3 @@ +Test-Command: testlog4qt.sh +Depends: libukui-log4qt-dev +Restrictions: diff --git a/debian/tests/testlog4qt.sh b/debian/tests/testlog4qt.sh new file mode 100755 index 0000000..7d87530 --- /dev/null +++ b/debian/tests/testlog4qt.sh @@ -0,0 +1,5 @@ +#!/bin/sh + +if [ -f '/usr/lib/libukui-log4qt.so' ] then + exit 0 +fi diff --git a/src/Makefile.am b/src/Makefile.am index dd953a0..089176d 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -1,5 +1,5 @@ NULL = -SUBDIRS = accounts common date hardware language network os \ - other personal security software updates \ +SUBDIRS = accounts common hardware language network \ + other personal security updates \ $(NULL) diff --git a/src/hardware/keyboard/Makefile.am b/src/hardware/keyboard/Makefile.am index 48c5043..2d56e83 100644 --- a/src/hardware/keyboard/Makefile.am +++ b/src/hardware/keyboard/Makefile.am @@ -22,32 +22,16 @@ keyboard-generated.h keyboard-generated.c: $(KEY_XML) #Generata binary file -lib_LTLIBRARIES = libukui-xkbgeneralclient.la libukui-interfaceclient.la libukui-keyboardclient.la +lib_LTLIBRARIES = libukui-interfaceclient.la libukui-keyboardclient.la #gcc -wall: displays all the errors and warning information when compiling #gcc -g: add the debugging code when compiling COMM_CFS = -Wall -g -#Add the dependent source file for libxkbgeneralclient.la -#xkbgeneral-generated.c must be front of kylin-xkbgeneral-interface.c -libukui_xkbgeneralclient_la_SOURCES = xkbgeneral-generated.c kylin-xkbgeneral-interface.c \ - $(NULL) - #The header files that need to be installed -include_HEADERS= kylin-xkbgeneral-interface.h \ - kylin-interface-interface.h \ - kylin-keyboard-interface.h \ - $(NULL) - -#Additional C compiler flags -libukui_xkbgeneralclient_la_CFLAGS= $(COMM_CFS) \ - $(GLIB_2_CFLAGS) $(GIO_2_CFLAGS) $(GIO_UNIX_2_CFLAGS) \ - $(NULL) - -#Additional link objects -libukui_xkbgeneralclient_la_LDFLAGS= $(COMM_PRINT) \ - $(GLIB_2_LIBS) $(GIO_2_LIBS) $(GIO_UNIX_2_LIBS) \ - $(NULL) +include_HEADERS= kylin-interface-interface.h \ + kylin-keyboard-interface.h \ + $(NULL) #Add the dependent source file for libinterfaceclient.la #interface-generated.c must be front of kylin-interface-interface.c From b3b9312b6e0a8221f0116a939ccc884602190a57 Mon Sep 17 00:00:00 2001 From: winnerym100 Date: Wed, 21 Jul 2021 18:35:58 +0800 Subject: [PATCH 16/35] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E5=B9=B3=E5=8F=B0?= =?UTF-8?q?=E5=85=AC=E5=85=B1=E6=8E=A5=E5=8F=A3=E5=BA=93libukui-common?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- debian/control | 20 +++ debian/libukui-common-dev.install | 4 + debian/libukui-common0.install | 1 + src/common/Makefile.am | 16 ++- src/common/kylin-common.c | 218 ++++++++++++++++++++++++++++++ src/common/kylin-common.h | 90 ++++++++++++ src/common/kylin-ini.c | 116 ++++++++++++++++ src/common/kylin-ini.h | 29 ++++ 8 files changed, 493 insertions(+), 1 deletion(-) create mode 100644 debian/libukui-common-dev.install create mode 100644 debian/libukui-common0.install create mode 100644 src/common/kylin-common.c create mode 100644 src/common/kylin-common.h create mode 100644 src/common/kylin-ini.c create mode 100644 src/common/kylin-ini.h diff --git a/debian/control b/debian/control index 93d6a14..5dbf922 100644 --- a/debian/control +++ b/debian/control @@ -504,3 +504,23 @@ Description: log4qt interface and related libraries. . The package contains development files for qt logging. + +Package: libukui-common0 +Architecture: any +Depends: ${shlibs:Depends}, ${misc:Depends} +Description: common module + UKUI interface provides the interface for system configuration + and related libraries. + . + The package contains common libraries. + +Package: libukui-common-dev +Architecture: any +Section: libdevel +Depends: ${misc:Depends}, + libukui-common0 (= ${binary:Version}) +Description: common interface + UKUI interface provides the interface for system configuration + and related libraries. + . + The package contains development files for platform common info. diff --git a/debian/libukui-common-dev.install b/debian/libukui-common-dev.install new file mode 100644 index 0000000..39cd608 --- /dev/null +++ b/debian/libukui-common-dev.install @@ -0,0 +1,4 @@ +usr/include/ukuisdk/kylin-common.h +usr/lib/*/libukui-common.a +usr/lib/*/libukui-common.la +usr/lib/*/libukui-common.so diff --git a/debian/libukui-common0.install b/debian/libukui-common0.install new file mode 100644 index 0000000..7f02dfe --- /dev/null +++ b/debian/libukui-common0.install @@ -0,0 +1 @@ +usr/lib/*/libukui-common.so.* diff --git a/src/common/Makefile.am b/src/common/Makefile.am index fe913d5..362ec5d 100644 --- a/src/common/Makefile.am +++ b/src/common/Makefile.am @@ -1,10 +1,23 @@ #Generata binary file -lib_LTLIBRARIES = libukui-print.la libukui-gsettings.la +lib_LTLIBRARIES = libukui-print.la libukui-gsettings.la libukui-common.la #gcc -wall: displays all the errors and warning information when compiling #gcc -g: add the debugging code when compiling COMM_CFS = -Wall -g +#Add the dependent source file for libukui-common.la +libukui_common_la_SOURCES = kylin-common.c \ + kylin-ini.c \ + $(NULL) + +#Additional C compiler flags +libukui_common_la_CFLAGS= $(COMM_CFS) \ + $(NULL) + +#Additional link objects +libukui_common_la_LDFLAGS= \ + $(NULL) + #Add the dependent source file for libukui-print.la libukui_print_la_SOURCES = kylin-print.c \ $(NULL) @@ -15,6 +28,7 @@ libukui_gsettings_la_SOURCES = kylin-gsettings-set.c \ #The header files that need to be installed include_HEADERS= \ + kylin-common.h \ kylin-print.h \ kylin-gsettings-set.h \ $(NULL) diff --git a/src/common/kylin-common.c b/src/common/kylin-common.c new file mode 100644 index 0000000..5f0c536 --- /dev/null +++ b/src/common/kylin-common.c @@ -0,0 +1,218 @@ +/* + * Copyright (C) 2021 Tianjin KYLIN Information Technology Co., Ltd. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see +#include +#include +#include + +#include "kylin-ini.h" + +#define LSB_RELEASE_FILE "/etc/lsb-release" /* lsb-release文件路径 */ +#define OS_RELEASE_FILE "/etc/os-release" /* os-release文件路径 */ +#define KYINFO_FILE "/etc/.kyinfo" /* kyinfo文件路径 */ +#define CPUINFO_FILE "/proc/cpuinfo" /* cpuinfo文件路径 */ +#define RELEASEFILE_LINE_MAX 256 /* 最大解析行行数 */ +#define RELEASEFILE_LINE_MAX_LEN 256 /* 最大解析行长度 */ +#define RELEASEFILE_KEY_MAX_LEN 64 /* 最大key长度 */ +#define RELEASEFILE_VALUE_MAX_LEN 256 /* 最大value长度 预留'\0', '='*/ +#define RELEASEFILE_SPLIT_CHAR '=' /* key和value的分隔符 */ +#define PROJECT_CODENAME "PROJECT_CODENAME" +#define CPUINFO_MODELNAME "model name" + +//去除尾部空白字符 包括\t \n \r +/* +标准的空白字符包括: +' ' (0x20) space (SPC) 空格符 +'\t' (0x09) horizontal tab (TAB) 水平制表符 +'\n' (0x0a) newline (LF) 换行符 +'\v' (0x0b) vertical tab (VT) 垂直制表符 +'\f' (0x0c) feed (FF) 换页符 +'\r' (0x0d) carriage return (CR) 回车符 +//windows \r\n linux \n mac \r +*/ +static char *rtrim(char *str) +{ + if(str == NULL || *str == '\0') { + return str; + } + int len = strlen(str); + char *p = str + len - 1; + while(p >= str && (isspace(*p) || *p == '\"')) { + *p = '\0'; --p; + } + return str; +} + +//去除首部空格 +static char *ltrim(char *str) +{ + if(str == NULL || *str == '\0') { + return str; + } + int len = 0; + char *p = str; + while(*p != '\0' && (isspace(*p) || *p == '\"')) { + ++p; ++len; + } + memmove(str, p, strlen(str) - len + 1); + return str; +} + +//去除首尾空格 +static char *trim(char *str) +{ + str = rtrim(str); + str = ltrim(str); + return str; +} + +// 根据key获取value,成功返回 >0 否则 返回 <= 0 +static int file_get_keyvalue(const char *path, const char *key, char *value, int value_max_len, const char chSplit) +{ + if (path == NULL || key == NULL || value == NULL || value_max_len <= 0) { + return -1; + } + int ret = 0; + int cnt = 0; + int key_len = 0; + int line_len = 0; + int value_len = 0; + FILE *fp = NULL; + char line_buf[RELEASEFILE_LINE_MAX_LEN] = {0}; + + /* 合法性判断 */ + if (NULL == path || NULL == key || NULL == value || 0 >= value_max_len) { + return -1; + } + + key_len = strlen(key); + if (0 >= key_len || RELEASEFILE_KEY_MAX_LEN < key_len) { + return -2; + } + + if (F_OK != access(path, F_OK)) { + return -3; + } + + /* 打开文件 */ + fp = fopen(path, "r"); + if (NULL == fp) { + return -4; + } + + /* 遍历行,匹配Key */ + while(NULL != fgets(line_buf, RELEASEFILE_LINE_MAX_LEN-1, fp)) { + line_len = strlen(line_buf); + if (line_len > key_len) { + /* 找到key */ + //找到非空格的首字符 + char *pStart = line_buf; + int nSplitIndex = 0; + while(pStart != (line_buf+line_len) && isspace(*pStart)) { + ++pStart; ++nSplitIndex; + } + if (0 == strncmp(pStart, key, key_len)) { + pStart = pStart + key_len; + nSplitIndex = nSplitIndex + key_len; + //跳过空格字符 + while(pStart != (line_buf+line_len) && isspace(*pStart)) { + ++pStart; ++nSplitIndex; + } + if (pStart != (line_buf+line_len) && *pStart == chSplit) { + ret = 1; + key_len = nSplitIndex; + break; + } + } + } + memset(line_buf, 0, sizeof(line_buf)); + + /* 最大查找行限制 */ + cnt++; + if (RELEASEFILE_LINE_MAX < cnt) { + break; + } + } + + /* 关闭文件 */ + fclose(fp); + fp = NULL; + + /* 找到key,返回value */ + if (1 == ret) { + value_len = line_len - key_len - 1; + if (0 < value_len) { + if (value_len > value_max_len) { + value_len = value_max_len; + } + /* 拷贝value */ + strncpy(value, &line_buf[key_len + 1], value_len); + value[value_len] = '\0'; + + /* 去掉结尾的换行符 */ + trim(value); + } else { + value[0] = '\0'; + } + } + return ret; +} + +int common_get_xdgsessiontype(char *xdgSessionType, int max_len) +{ + if (xdgSessionType == NULL || max_len <= 0) + return -1; + char *strSessionType = getenv("XDG_SESSION_TYPE"); + if (!strSessionType) { + return -2; + } + unsigned int nValidLen = max_len < strlen(strSessionType) ? max_len: strlen(strSessionType); + memcpy(xdgSessionType, strSessionType, nValidLen*sizeof(char)); + return nValidLen; +} + +int common_get_lsbrelease(const char *key, char *value, int value_max_len) +{ + return file_get_keyvalue(LSB_RELEASE_FILE, key, value, value_max_len, RELEASEFILE_SPLIT_CHAR); +} + +int common_get_osrelease(const char *key, char *value, int value_max_len) +{ + return file_get_keyvalue(OS_RELEASE_FILE, key, value, value_max_len, RELEASEFILE_SPLIT_CHAR); +} + +int common_get_prjcodename(char *value, int value_max_len) +{ + int nResult = common_get_lsbrelease(PROJECT_CODENAME, value, value_max_len); + if (nResult <= 0) { + nResult = common_get_osrelease(PROJECT_CODENAME, value, value_max_len); + } + return nResult; +} + +int common_get_kyinfo(const char *session, const char *key, char *value, int value_max_len) +{ + return getIniKeyString(KYINFO_FILE, session, key, value, value_max_len); +} + +int common_get_cpumodelname(char *modelName, int max_len) +{ + return file_get_keyvalue(CPUINFO_FILE, CPUINFO_MODELNAME, modelName, max_len, ':'); +} \ No newline at end of file diff --git a/src/common/kylin-common.h b/src/common/kylin-common.h new file mode 100644 index 0000000..873031f --- /dev/null +++ b/src/common/kylin-common.h @@ -0,0 +1,90 @@ +/* + * Copyright (C) 2021 Tianjin KYLIN Information Technology Co., Ltd. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * 函数名称:common_get_xdgsessiontype + * 功能: 获取区分x11与wayland的环境变量值 + * 参数1:xdgSessionType xdg会话类型字符串指针(out) + * 参数2:max_len xdg会话类型字符串缓存大小(in) + * 返回值:> 0 成功 否则失败 + **/ +int common_get_xdgsessiontype(char *xdgSessionType, int max_len); + +/** + * 函数名称:common_get_lsbrelease + * 功能:根据lsbrelease信息的键获取值 + * 参数1:key lsbrelease信息的键(in) + * 参数2:value lsbrelease信息的值(out) + * 参数3:value_max_len 值缓存区的大小(in) + * 返回值:> 0 成功 否则失败 + **/ +int common_get_lsbrelease(const char *key, char *value, int value_max_len); + +/** + * 函数名称:common_get_osrelease + * 功能:根据osrelease信息的键获取值 + * 参数1:key osrelease信息的键(in) + * 参数2:value osrelease信息的值(out) + * 参数3:value_max_len 值缓存区的大小(in) + * 返回值:> 0 成功 否则失败 + **/ +int common_get_osrelease(const char *key, char *value, int value_max_len); + +/** + * 函数名称:common_get_kyinfo + * 功能:根据kyinfo的键获取值 + * 参数1:session kyinfo的session值(in) + * 参数2:key kyinfo的键(in) + * 参数3:value kyinfo的值(out) + * 参数4:value_max_len 值缓存区的大小(in) + * 返回值:>= 0 成功 否则失败 + **/ +int common_get_kyinfo(const char *session, const char *key, char *value, int value_max_len); + +/** + * 函数名称:common_get_prjcodename + * 功能:根据PROJECT_CODENAME字段的值 + * 参数1:value PROJECT_CODENAME字段的值(out) + * 参数2:value_max_len 值缓存区的大小(in) + * 返回值:> 0 成功 否则失败 + **/ +int common_get_prjcodename(char *value, int value_max_len); + +/** + * 函数名称:common_get_cpumodelname + * 功能:获取CPU型号 + * 参数1:modelName CPU型号信息(out) + * 参数2:max_len CPU型号缓存区的大小(in) + * 返回值:> 0 成功 否则失败 + **/ +int common_get_cpumodelname(char *modelName, int max_len); + +#ifdef __cplusplus +} +#endif + +#endif // __KYLINCOMMON_H__ \ No newline at end of file diff --git a/src/common/kylin-ini.c b/src/common/kylin-ini.c new file mode 100644 index 0000000..814b726 --- /dev/null +++ b/src/common/kylin-ini.c @@ -0,0 +1,116 @@ +/* + * Copyright (C) 2021 Tianjin KYLIN Information Technology Co., Ltd. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see +#include + +// getIniKeyString 读取ini键值 +int getIniKeyString(const char *filename, const char *session, const char *key, char *value, int value_max_len) +{ + if (filename == NULL || session == NULL || key == NULL || value == NULL || value_max_len <= 0) + return -1; // 参数错误 + FILE *fp = NULL; + int flag = 0; + char sSession[64], *wTmp; + char sLine[1024]; + snprintf(sSession, 64, "[%s]", session); + if(NULL == (fp = fopen(filename, "r"))) { + perror("fopen"); + return -1; + } + while (NULL != fgets(sLine, 1024, fp)) { + // 这是注释行 + if (0 == strncmp("//", sLine, 2)) continue; + if ('#' == sLine[0]) continue; + wTmp = strchr(sLine, '='); + if ((NULL != wTmp) && (1 == flag)) { + if (0 == strncmp(key, sLine, strlen(key))) { // 长度依文件读取的为准 + sLine[strlen(sLine) - 1] = '\0'; + fclose(fp); + while(*(wTmp + 1) == ' '){ + wTmp++; + } + int nValidLen = strlen(wTmp + 1); + nValidLen = nValidLen < value_max_len ? nValidLen : value_max_len; + strncpy(value, wTmp + 1, nValidLen); + return 0; + } + } else { + if (0 == strncmp(sSession, sLine, strlen(sSession))) { // 长度依文件读取的为准 + flag = 1; // 找到标题位置 + } + } + } + fclose(fp); + return -1; +} + +// 设置ini键值 +int setIniKeyString(const char *filename, const char *session, const char *key, char *value) +{ + if (filename == NULL || session == NULL || key == NULL || value == NULL) + return -1; // 参数错误 + FILE *fpr = NULL, *fpw = NULL; + int flag = 0; + char sLine[1024] = {0}, sSession[64] = {0}, *wTmp = NULL; + snprintf(sSession, 64, "[%s]", session); + if (NULL == (fpr = fopen(filename, "r"))) + return -1;// 读取原文件 + + snprintf(sLine, 256, "%s.tmp", filename); + if (NULL == (fpw = fopen(sLine, "w"))) { + fclose(fpr); + fpr = NULL; + return -1;// 写入临时文件 + } + + while (NULL != fgets(sLine, 1024, fpr)) { + if (2 != flag) { // 如果找到要修改的那一行,则不会执行内部的操作 + wTmp = strchr(sLine, '='); + if ((NULL != wTmp) && (1 == flag)) { + if (0 == strncmp(key, sLine, strlen(key))) { // 长度依文件读取的为准 + flag = 2;// 更改值,方便写入文件 + snprintf(wTmp + 1, 256, " %s\n", value); + break; + } + } else { + if (0 == strncmp(sSession, sLine, strlen(sSession))) { // 长度依文件读取的为准 + flag = 1; // 找到标题位置 + } + } + } + fputs(sLine, fpw); // 写入临时文件 + } + if (flag == 0) { // 未找到session + char wBuffer[1024] = {0}; + snprintf(wBuffer, 1024, "%s\n", sSession); + fputs(wBuffer, fpw); // 写入会话 + snprintf(wBuffer, 1024, "%s = %s\n", key, value); + fputs(wBuffer, fpw); // 写入键值 + } else if (flag == 1) { // 待完善 + char wBuffer[1024] = {0}; + snprintf(wBuffer, 1024, "%s = %s\n", key, value); + fputs(wBuffer, fpw); // 写入键值 + } + fclose(fpr); + fclose(fpw); + snprintf(sLine, 256, "%s.tmp", filename); + return rename(sLine, filename);// 将临时文件更新到原文件 +} diff --git a/src/common/kylin-ini.h b/src/common/kylin-ini.h new file mode 100644 index 0000000..1e7722e --- /dev/null +++ b/src/common/kylin-ini.h @@ -0,0 +1,29 @@ +/* + * Copyright (C) 2021 Tianjin KYLIN Information Technology Co., Ltd. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see +#include + +int getIniKeyString(const char *filename, const char *session, const char *key, char *value, int value_max_len); + +int setIniKeyString(const char *filename, const char *session, const char *key, char *value); + +#endif //__KYLININI_H__ \ No newline at end of file From 3ca0e54b3edcefc767dec00876b613fdc9025739 Mon Sep 17 00:00:00 2001 From: winnerym100 Date: Thu, 22 Jul 2021 14:17:29 +0800 Subject: [PATCH 17/35] =?UTF-8?q?=E4=BC=98=E5=8C=96=E5=B9=B3=E5=8F=B0?= =?UTF-8?q?=E5=85=AC=E5=85=B1=E6=8E=A5=E5=8F=A3=E5=BA=93libukui-common?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/common/kylin-common.c | 59 ++++++--------------------- src/common/kylin-common.h | 9 +++++ src/common/kylin-ini.c | 84 +++++++++++++++++++++++++++++++++++---- src/common/kylin-ini.h | 9 +++++ 4 files changed, 107 insertions(+), 54 deletions(-) diff --git a/src/common/kylin-common.c b/src/common/kylin-common.c index 5f0c536..856e334 100644 --- a/src/common/kylin-common.c +++ b/src/common/kylin-common.c @@ -36,52 +36,6 @@ #define PROJECT_CODENAME "PROJECT_CODENAME" #define CPUINFO_MODELNAME "model name" -//去除尾部空白字符 包括\t \n \r -/* -标准的空白字符包括: -' ' (0x20) space (SPC) 空格符 -'\t' (0x09) horizontal tab (TAB) 水平制表符 -'\n' (0x0a) newline (LF) 换行符 -'\v' (0x0b) vertical tab (VT) 垂直制表符 -'\f' (0x0c) feed (FF) 换页符 -'\r' (0x0d) carriage return (CR) 回车符 -//windows \r\n linux \n mac \r -*/ -static char *rtrim(char *str) -{ - if(str == NULL || *str == '\0') { - return str; - } - int len = strlen(str); - char *p = str + len - 1; - while(p >= str && (isspace(*p) || *p == '\"')) { - *p = '\0'; --p; - } - return str; -} - -//去除首部空格 -static char *ltrim(char *str) -{ - if(str == NULL || *str == '\0') { - return str; - } - int len = 0; - char *p = str; - while(*p != '\0' && (isspace(*p) || *p == '\"')) { - ++p; ++len; - } - memmove(str, p, strlen(str) - len + 1); - return str; -} - -//去除首尾空格 -static char *trim(char *str) -{ - str = rtrim(str); - str = ltrim(str); - return str; -} // 根据key获取value,成功返回 >0 否则 返回 <= 0 static int file_get_keyvalue(const char *path, const char *key, char *value, int value_max_len, const char chSplit) @@ -167,7 +121,7 @@ static int file_get_keyvalue(const char *path, const char *key, char *value, int value[value_len] = '\0'; /* 去掉结尾的换行符 */ - trim(value); + trim(value, 1); } else { value[0] = '\0'; } @@ -215,4 +169,15 @@ int common_get_kyinfo(const char *session, const char *key, char *value, int val int common_get_cpumodelname(char *modelName, int max_len) { return file_get_keyvalue(CPUINFO_FILE, CPUINFO_MODELNAME, modelName, max_len, ':'); +} + +int common_get_spechdplatform(char *platformName, int max_len) +{ + if (platformName == NULL || max_len <= 0) + return -1; + char strDefault[] = "default"; + int validLen = strlen(strDefault); + validLen = validLen > max_len ? max_len : validLen; + strncpy(platformName, strDefault, validLen); + return validLen; } \ No newline at end of file diff --git a/src/common/kylin-common.h b/src/common/kylin-common.h index 873031f..1ded6c6 100644 --- a/src/common/kylin-common.h +++ b/src/common/kylin-common.h @@ -83,6 +83,15 @@ int common_get_prjcodename(char *value, int value_max_len); **/ int common_get_cpumodelname(char *modelName, int max_len); +/** + * 函数名称:common_get_spechdplatform + * 功能:获取特定硬件平台信息 + * 参数1:platformName 特定硬件平台信息(out) + * 参数2:max_len 特定硬件平台缓存区的大小(in) + * 返回值:> 0 成功 否则失败 + **/ +int common_get_spechdplatform(char *platformName, int max_len); + #ifdef __cplusplus } #endif diff --git a/src/common/kylin-ini.c b/src/common/kylin-ini.c index 814b726..8ba3b88 100644 --- a/src/common/kylin-ini.c +++ b/src/common/kylin-ini.c @@ -20,15 +20,77 @@ #include #include +#include +#include + +//去除尾部空白字符 包括\t \n \r +/* +标准的空白字符包括: +' ' (0x20) space (SPC) 空格符 +'\t' (0x09) horizontal tab (TAB) 水平制表符 +'\n' (0x0a) newline (LF) 换行符 +'\v' (0x0b) vertical tab (VT) 垂直制表符 +'\f' (0x0c) feed (FF) 换页符 +'\r' (0x0d) carriage return (CR) 回车符 +//windows \r\n linux \n mac \r +*/ +char *rtrim(char *str, int containQuot) +{ + if(str == NULL || *str == '\0') { + return str; + } + int len = strlen(str); + char *p = str + len - 1; + if (containQuot) { + while(p >= str && (isspace(*p) || *p == '\"')) { + *p = '\0'; --p; + } + } else { + while(p >= str && isspace(*p)) { + *p = '\0'; --p; + } + } + return str; +} + +//去除首部空格 +char *ltrim(char *str, int containQuot) +{ + if(str == NULL || *str == '\0') { + return str; + } + int len = 0; + char *p = str; + if (containQuot) { + while(*p != '\0' && (isspace(*p) || *p == '\"')) { + ++p; ++len; + } + } else { + while(*p != '\0' && isspace(*p)) { + ++p; ++len; + } + } + memmove(str, p, strlen(str) - len + 1); + return str; +} + +//去除首尾空格 +char *trim(char *str, int containQuot) +{ + str = rtrim(str, containQuot); + str = ltrim(str, containQuot); + return str; +} // getIniKeyString 读取ini键值 int getIniKeyString(const char *filename, const char *session, const char *key, char *value, int value_max_len) { if (filename == NULL || session == NULL || key == NULL || value == NULL || value_max_len <= 0) return -1; // 参数错误 + // 清空目标缓存 FILE *fp = NULL; int flag = 0; - char sSession[64], *wTmp; + char sSession[64], *wTmp = NULL; char sLine[1024]; snprintf(sSession, 64, "[%s]", session); if(NULL == (fp = fopen(filename, "r"))) { @@ -37,24 +99,32 @@ int getIniKeyString(const char *filename, const char *session, const char *key, } while (NULL != fgets(sLine, 1024, fp)) { // 这是注释行 + trim(sLine, 0); if (0 == strncmp("//", sLine, 2)) continue; if ('#' == sLine[0]) continue; wTmp = strchr(sLine, '='); if ((NULL != wTmp) && (1 == flag)) { - if (0 == strncmp(key, sLine, strlen(key))) { // 长度依文件读取的为准 - sLine[strlen(sLine) - 1] = '\0'; + int keyLen = wTmp - sLine; + char keyName[256] = {0}; + strncpy(keyName, sLine, keyLen); + rtrim(keyName, 0); + keyLen = strlen(keyName) > strlen(key) ? strlen(keyName) : strlen(key); + if (0 == strncmp(key, keyName, keyLen)) { // 长度依文件读取的为准 fclose(fp); - while(*(wTmp + 1) == ' '){ - wTmp++; - } int nValidLen = strlen(wTmp + 1); nValidLen = nValidLen < value_max_len ? nValidLen : value_max_len; strncpy(value, wTmp + 1, nValidLen); + trim(value, 1); return 0; } } else { if (0 == strncmp(sSession, sLine, strlen(sSession))) { // 长度依文件读取的为准 - flag = 1; // 找到标题位置 + flag = 1; // 找到目标session位置 + } else if (flag == 1) { // 找到其他空行或session + wTmp = strchr(sLine, '['); + if (NULL != wTmp) { + flag = 0; + } } } } diff --git a/src/common/kylin-ini.h b/src/common/kylin-ini.h index 1e7722e..614f912 100644 --- a/src/common/kylin-ini.h +++ b/src/common/kylin-ini.h @@ -22,6 +22,15 @@ #include #include +// 去除尾部空格 +char *rtrim(char *str, int containQuot); + +// 去除头部空格 +char *ltrim(char *str, int containQuot); + +// 去除前后空格 +char *trim(char *str, int containQuot); + int getIniKeyString(const char *filename, const char *session, const char *key, char *value, int value_max_len); int setIniKeyString(const char *filename, const char *session, const char *key, char *value); From 41ac324ece7585747f769f1a0a9f44a68abe3a34 Mon Sep 17 00:00:00 2001 From: handsome-feng Date: Thu, 29 Jul 2021 09:54:19 +0800 Subject: [PATCH 18/35] Fix spelling error --- src/log4qt/log4qt/helpers/optionconverter.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/log4qt/log4qt/helpers/optionconverter.cpp b/src/log4qt/log4qt/helpers/optionconverter.cpp index 15fb645..a0a7b34 100644 --- a/src/log4qt/log4qt/helpers/optionconverter.cpp +++ b/src/log4qt/log4qt/helpers/optionconverter.cpp @@ -100,7 +100,7 @@ namespace Log4Qt end = value.indexOf(end_subst, i + begin_length); if (end == -1) { - LogError e = LOG4QT_ERROR(QT_TR_NOOP("Missing closing bracket for opening bracket at %1. Invalid subsitution in value %2."), + LogError e = LOG4QT_ERROR(QT_TR_NOOP("Missing closing bracket for opening bracket at %1. Invalid substitution in value %2."), CONFIGURATOR_INVALID_SUBSTITUTION_ERROR, "Log4Qt::OptionConverter"); e << begin << value; From 605eae56d2784904d4baa66393fb456dbdab7cbf Mon Sep 17 00:00:00 2001 From: handsome-feng Date: Thu, 29 Jul 2021 09:54:19 +0800 Subject: [PATCH 19/35] Fix spelling error --- src/log4qt/log4qt/helpers/optionconverter.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/log4qt/log4qt/helpers/optionconverter.cpp b/src/log4qt/log4qt/helpers/optionconverter.cpp index 15fb645..a0a7b34 100644 --- a/src/log4qt/log4qt/helpers/optionconverter.cpp +++ b/src/log4qt/log4qt/helpers/optionconverter.cpp @@ -100,7 +100,7 @@ namespace Log4Qt end = value.indexOf(end_subst, i + begin_length); if (end == -1) { - LogError e = LOG4QT_ERROR(QT_TR_NOOP("Missing closing bracket for opening bracket at %1. Invalid subsitution in value %2."), + LogError e = LOG4QT_ERROR(QT_TR_NOOP("Missing closing bracket for opening bracket at %1. Invalid substitution in value %2."), CONFIGURATOR_INVALID_SUBSTITUTION_ERROR, "Log4Qt::OptionConverter"); e << begin << value; From f5d8583da287e0c7fa51847c33513219264d63ca Mon Sep 17 00:00:00 2001 From: handsome-feng Date: Thu, 29 Jul 2021 11:49:44 +0800 Subject: [PATCH 20/35] Add .gitattributes --- .gitattributes | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 .gitattributes diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..b62025d --- /dev/null +++ b/.gitattributes @@ -0,0 +1,2 @@ +debian/changelog merge=ours +debian/source/format merge=ours From 251c80e21ddaaf1af95c435a04be9bd9a30b6aa6 Mon Sep 17 00:00:00 2001 From: handsome-feng Date: Thu, 29 Jul 2021 15:05:45 +0800 Subject: [PATCH 21/35] 1.0.2-1 --- debian/changelog | 4 ++-- debian/source/format | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/debian/changelog b/debian/changelog index a781a6b..af3f47e 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,8 +1,8 @@ -ukui-interface (1.0.1.1-1) focal; urgency=medium +ukui-interface (1.0.2-1) experimental; urgency=medium * New upstream release. - -- handsome_feng Thu, 17 Jun 2021 15:23:30 +0800 + -- handsome_feng Thu, 29 Jul 2021 11:51:46 +0800 ukui-interface (1.0.0-2) unstable; urgency=low diff --git a/debian/source/format b/debian/source/format index 89ae9db..163aaf8 100644 --- a/debian/source/format +++ b/debian/source/format @@ -1 +1 @@ -3.0 (native) +3.0 (quilt) From 15636edd963c21e10e03259aea2e8a7e400ed4fc Mon Sep 17 00:00:00 2001 From: handsome-feng Date: Thu, 29 Jul 2021 16:22:14 +0800 Subject: [PATCH 22/35] update debian/copyright --- debian/copyright | 199 +++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 186 insertions(+), 13 deletions(-) diff --git a/debian/copyright b/debian/copyright index 6ffd241..d20d038 100644 --- a/debian/copyright +++ b/debian/copyright @@ -4,12 +4,74 @@ Upstream-Contact: liuhao Source: https://github.com/ukui/ukui-interface Files: * -Copyright: 2019 Tianjin KYLIN Information Technology Co., Ltd. +Copyright: 2019, Tianjin KYLIN Information Technology Co., Ltd. +License: GPL-3.0+ + +Files: debian/* +Copyright: 2019, liuhao +License: GPL-3.0+ + +Files: po/Makevars +Copyright: for their translations to this person +License: GPL-3.0+ + +Files: src/accounts/user/* +Copyright: 2019, 2021, Tianjin KYLIN Information Technology Co., Ltd. +License: GPL-3+ + +Files: src/accounts/user/Makefile.am +Copyright: 2019, Tianjin KYLIN Information Technology Co., Ltd. +License: GPL-3.0+ + +Files: src/common/* +Copyright: 2019, 2021, Tianjin KYLIN Information Technology Co., Ltd. +License: GPL-3+ + +Files: src/common/Makefile.am +Copyright: 2019, Tianjin KYLIN Information Technology Co., Ltd. +License: GPL-3.0+ + +Files: src/date/dttm/* +Copyright: 2019, 2021, Tianjin KYLIN Information Technology Co., Ltd. +License: GPL-3+ + +Files: src/date/dttm/Makefile.am +Copyright: 2019, Tianjin KYLIN Information Technology Co., Ltd. +License: GPL-3.0+ + +Files: src/hardware/* +Copyright: 2019, 2021, Tianjin KYLIN Information Technology Co., Ltd. +License: GPL-3+ + +Files: src/hardware/Makefile.am +Copyright: 2019, Tianjin KYLIN Information Technology Co., Ltd. +License: GPL-3.0+ + +Files: src/hardware/keyboard/Makefile.am +Copyright: 2019, Tianjin KYLIN Information Technology Co., Ltd. +License: GPL-3.0+ + +Files: src/hardware/mouse/Makefile.am +Copyright: 2019, Tianjin KYLIN Information Technology Co., Ltd. +License: GPL-3.0+ + +Files: src/hardware/power/Makefile.am +Copyright: 2019, Tianjin KYLIN Information Technology Co., Ltd. +License: GPL-3.0+ + +Files: src/hardware/touchpad/Makefile.am +Copyright: 2019, Tianjin KYLIN Information Technology Co., Ltd. +License: GPL-3.0+ + +Files: src/log4qt/* +Copyright: 2019, 2021, Tianjin KYLIN Information Technology Co., Ltd. +License: GPL-3+ + +Files: src/log4qt/Doxyfile +Copyright: 2019, Tianjin KYLIN Information Technology Co., Ltd. License: GPL-3.0+ Files: src/log4qt/doc/* - src/log4qt/log4qt/* - src/log4qt/tests/* Copyright: 2007 - 2009 Martin Heinrich License: Apache-2.0 Licensed under the Apache License, Version 2.0 (the "License"); @@ -27,20 +89,131 @@ License: Apache-2.0 On Debian systems, the complete text of the Apache License Version 2.0 can be found in `/usr/share/common-licenses/Apache-2.0'. -Files: src/log4qt/ukui-log4qt.h - src/log4qt/ukui-log4qt.cpp - src/log4qt/ukui-logconfigurator.h - src/log4qt/ukui-logconfigurator.cpp - src/log4qt/ukui-logrolling.h - src/log4qt/ukui-logrolling.cpp - src/log4qt/ukui-logmacros.h -Copyright: 2021 Yang Min +Files: src/log4qt/log4qt/* +Copyright: 2007-2009, Martin Heinrich +License: Apache-2.0 + 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. + . + On Debian systems, the complete text of the Apache License Version 2.0 + can be found in `/usr/share/common-licenses/Apache-2.0'. + +Files: src/log4qt/log4qt/helpers/asyncdispatcher.cpp + src/log4qt/log4qt/helpers/asyncdispatcher.h +Copyright: 2019, 2021, Tianjin KYLIN Information Technology Co., Ltd. +License: GPL-3+ + 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. + . + On Debian systems, the complete text of the Apache License Version 2.0 + can be found in `/usr/share/common-licenses/Apache-2.0'. + +Files: src/log4qt/tests/* +Copyright: 2007-2009, Martin Heinrich +License: Apache-2.0 + 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. + . + On Debian systems, the complete text of the Apache License Version 2.0 + can be found in `/usr/share/common-licenses/Apache-2.0'. + +Files: src/network/network/* +Copyright: 2019, 2021, Tianjin KYLIN Information Technology Co., Ltd. +License: GPL-3+ + +Files: src/network/network/Makefile.am +Copyright: 2019, Tianjin KYLIN Information Technology Co., Ltd. License: GPL-3.0+ -Files: debian/* -Copyright: 2019 liuhao +Files: src/os/* +Copyright: 2019, 2021, Tianjin KYLIN Information Technology Co., Ltd. +License: GPL-3+ + +Files: src/os/Makefile.am +Copyright: 2019, Tianjin KYLIN Information Technology Co., Ltd. +License: GPL-3.0+ + +Files: src/os/subversion/Makefile.am +Copyright: 2019, Tianjin KYLIN Information Technology Co., Ltd. +License: GPL-3.0+ + +Files: src/os/sysinfo/Makefile.am +Copyright: 2019, Tianjin KYLIN Information Technology Co., Ltd. +License: GPL-3.0+ + +Files: src/personal/* +Copyright: 2019, 2021, Tianjin KYLIN Information Technology Co., Ltd. +License: GPL-3+ + +Files: src/personal/Makefile.am +Copyright: 2019, Tianjin KYLIN Information Technology Co., Ltd. +License: GPL-3.0+ + +Files: src/personal/background/Makefile.am +Copyright: 2019, Tianjin KYLIN Information Technology Co., Ltd. +License: GPL-3.0+ + +Files: src/personal/desktop/Makefile.am +Copyright: 2019, Tianjin KYLIN Information Technology Co., Ltd. License: GPL-3.0+ +Files: src/personal/font/Makefile.am +Copyright: 2019, Tianjin KYLIN Information Technology Co., Ltd. +License: GPL-3.0+ + +Files: src/personal/marcogeneral/Makefile.am +Copyright: 2019, Tianjin KYLIN Information Technology Co., Ltd. +License: GPL-3.0+ + +Files: src/software/defaultprograms/* +Copyright: 2019, 2021, Tianjin KYLIN Information Technology Co., Ltd. +License: GPL-3+ + +Files: src/software/defaultprograms/Makefile.am +Copyright: 2019, Tianjin KYLIN Information Technology Co., Ltd. +License: GPL-3.0+ + +License: GPL-3+ + This software is Copyright (c) 2021 by X. Ample. + . + This is free software, licensed under: + . + The GNU General Public License, Version 3, June 2007 + . + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; version 3 dated June, 2007, or (at + your option) any later version. + On Debian systems, the complete text of version 3 of the GNU General + Public License can be found in '/usr/share/common-licenses/GPL-3'. + License: GPL-3.0+ This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by From 6e5d6343db0926b4951169519152e04e23c88c27 Mon Sep 17 00:00:00 2001 From: handsome-feng Date: Thu, 29 Jul 2021 16:22:14 +0800 Subject: [PATCH 23/35] update debian/copyright --- debian/copyright | 199 +++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 186 insertions(+), 13 deletions(-) diff --git a/debian/copyright b/debian/copyright index 6ffd241..d20d038 100644 --- a/debian/copyright +++ b/debian/copyright @@ -4,12 +4,74 @@ Upstream-Contact: liuhao Source: https://github.com/ukui/ukui-interface Files: * -Copyright: 2019 Tianjin KYLIN Information Technology Co., Ltd. +Copyright: 2019, Tianjin KYLIN Information Technology Co., Ltd. +License: GPL-3.0+ + +Files: debian/* +Copyright: 2019, liuhao +License: GPL-3.0+ + +Files: po/Makevars +Copyright: for their translations to this person +License: GPL-3.0+ + +Files: src/accounts/user/* +Copyright: 2019, 2021, Tianjin KYLIN Information Technology Co., Ltd. +License: GPL-3+ + +Files: src/accounts/user/Makefile.am +Copyright: 2019, Tianjin KYLIN Information Technology Co., Ltd. +License: GPL-3.0+ + +Files: src/common/* +Copyright: 2019, 2021, Tianjin KYLIN Information Technology Co., Ltd. +License: GPL-3+ + +Files: src/common/Makefile.am +Copyright: 2019, Tianjin KYLIN Information Technology Co., Ltd. +License: GPL-3.0+ + +Files: src/date/dttm/* +Copyright: 2019, 2021, Tianjin KYLIN Information Technology Co., Ltd. +License: GPL-3+ + +Files: src/date/dttm/Makefile.am +Copyright: 2019, Tianjin KYLIN Information Technology Co., Ltd. +License: GPL-3.0+ + +Files: src/hardware/* +Copyright: 2019, 2021, Tianjin KYLIN Information Technology Co., Ltd. +License: GPL-3+ + +Files: src/hardware/Makefile.am +Copyright: 2019, Tianjin KYLIN Information Technology Co., Ltd. +License: GPL-3.0+ + +Files: src/hardware/keyboard/Makefile.am +Copyright: 2019, Tianjin KYLIN Information Technology Co., Ltd. +License: GPL-3.0+ + +Files: src/hardware/mouse/Makefile.am +Copyright: 2019, Tianjin KYLIN Information Technology Co., Ltd. +License: GPL-3.0+ + +Files: src/hardware/power/Makefile.am +Copyright: 2019, Tianjin KYLIN Information Technology Co., Ltd. +License: GPL-3.0+ + +Files: src/hardware/touchpad/Makefile.am +Copyright: 2019, Tianjin KYLIN Information Technology Co., Ltd. +License: GPL-3.0+ + +Files: src/log4qt/* +Copyright: 2019, 2021, Tianjin KYLIN Information Technology Co., Ltd. +License: GPL-3+ + +Files: src/log4qt/Doxyfile +Copyright: 2019, Tianjin KYLIN Information Technology Co., Ltd. License: GPL-3.0+ Files: src/log4qt/doc/* - src/log4qt/log4qt/* - src/log4qt/tests/* Copyright: 2007 - 2009 Martin Heinrich License: Apache-2.0 Licensed under the Apache License, Version 2.0 (the "License"); @@ -27,20 +89,131 @@ License: Apache-2.0 On Debian systems, the complete text of the Apache License Version 2.0 can be found in `/usr/share/common-licenses/Apache-2.0'. -Files: src/log4qt/ukui-log4qt.h - src/log4qt/ukui-log4qt.cpp - src/log4qt/ukui-logconfigurator.h - src/log4qt/ukui-logconfigurator.cpp - src/log4qt/ukui-logrolling.h - src/log4qt/ukui-logrolling.cpp - src/log4qt/ukui-logmacros.h -Copyright: 2021 Yang Min +Files: src/log4qt/log4qt/* +Copyright: 2007-2009, Martin Heinrich +License: Apache-2.0 + 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. + . + On Debian systems, the complete text of the Apache License Version 2.0 + can be found in `/usr/share/common-licenses/Apache-2.0'. + +Files: src/log4qt/log4qt/helpers/asyncdispatcher.cpp + src/log4qt/log4qt/helpers/asyncdispatcher.h +Copyright: 2019, 2021, Tianjin KYLIN Information Technology Co., Ltd. +License: GPL-3+ + 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. + . + On Debian systems, the complete text of the Apache License Version 2.0 + can be found in `/usr/share/common-licenses/Apache-2.0'. + +Files: src/log4qt/tests/* +Copyright: 2007-2009, Martin Heinrich +License: Apache-2.0 + 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. + . + On Debian systems, the complete text of the Apache License Version 2.0 + can be found in `/usr/share/common-licenses/Apache-2.0'. + +Files: src/network/network/* +Copyright: 2019, 2021, Tianjin KYLIN Information Technology Co., Ltd. +License: GPL-3+ + +Files: src/network/network/Makefile.am +Copyright: 2019, Tianjin KYLIN Information Technology Co., Ltd. License: GPL-3.0+ -Files: debian/* -Copyright: 2019 liuhao +Files: src/os/* +Copyright: 2019, 2021, Tianjin KYLIN Information Technology Co., Ltd. +License: GPL-3+ + +Files: src/os/Makefile.am +Copyright: 2019, Tianjin KYLIN Information Technology Co., Ltd. +License: GPL-3.0+ + +Files: src/os/subversion/Makefile.am +Copyright: 2019, Tianjin KYLIN Information Technology Co., Ltd. +License: GPL-3.0+ + +Files: src/os/sysinfo/Makefile.am +Copyright: 2019, Tianjin KYLIN Information Technology Co., Ltd. +License: GPL-3.0+ + +Files: src/personal/* +Copyright: 2019, 2021, Tianjin KYLIN Information Technology Co., Ltd. +License: GPL-3+ + +Files: src/personal/Makefile.am +Copyright: 2019, Tianjin KYLIN Information Technology Co., Ltd. +License: GPL-3.0+ + +Files: src/personal/background/Makefile.am +Copyright: 2019, Tianjin KYLIN Information Technology Co., Ltd. +License: GPL-3.0+ + +Files: src/personal/desktop/Makefile.am +Copyright: 2019, Tianjin KYLIN Information Technology Co., Ltd. License: GPL-3.0+ +Files: src/personal/font/Makefile.am +Copyright: 2019, Tianjin KYLIN Information Technology Co., Ltd. +License: GPL-3.0+ + +Files: src/personal/marcogeneral/Makefile.am +Copyright: 2019, Tianjin KYLIN Information Technology Co., Ltd. +License: GPL-3.0+ + +Files: src/software/defaultprograms/* +Copyright: 2019, 2021, Tianjin KYLIN Information Technology Co., Ltd. +License: GPL-3+ + +Files: src/software/defaultprograms/Makefile.am +Copyright: 2019, Tianjin KYLIN Information Technology Co., Ltd. +License: GPL-3.0+ + +License: GPL-3+ + This software is Copyright (c) 2021 by X. Ample. + . + This is free software, licensed under: + . + The GNU General Public License, Version 3, June 2007 + . + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; version 3 dated June, 2007, or (at + your option) any later version. + On Debian systems, the complete text of version 3 of the GNU General + Public License can be found in '/usr/share/common-licenses/GPL-3'. + License: GPL-3.0+ This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by From c88b819a1b236c81a363f63481e8c060cd4a9363 Mon Sep 17 00:00:00 2001 From: winnerym100 Date: Fri, 30 Jul 2021 14:51:58 +0800 Subject: [PATCH 24/35] =?UTF-8?q?=E4=BC=98=E5=8C=96common=E5=BA=93?= =?UTF-8?q?=E6=8E=A5=E5=8F=A3=EF=BC=8C=E5=8C=BA=E5=88=86c=E3=80=81C++?= =?UTF-8?q?=E7=89=88=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- debian/control | 2 +- debian/libukui-common-dev.install | 12 +- debian/libukui-common0.install | 3 +- src/common/Makefile.am | 32 ++- src/common/kylin-com4c.c | 220 ++++++++++++++++++ src/common/kylin-com4c.h | 90 +++++++ .../{kylin-common.c => kylin-com4cxx.cpp} | 108 ++++++--- src/common/kylin-com4cxx.h | 84 +++++++ src/common/kylin-common.h | 99 -------- src/common/kylin-ini.c | 113 +-------- src/common/kylin-ini.h | 16 +- 11 files changed, 520 insertions(+), 259 deletions(-) create mode 100644 src/common/kylin-com4c.c create mode 100644 src/common/kylin-com4c.h rename src/common/{kylin-common.c => kylin-com4cxx.cpp} (62%) create mode 100644 src/common/kylin-com4cxx.h delete mode 100644 src/common/kylin-common.h diff --git a/debian/control b/debian/control index 5dbf922..ebfc7c9 100644 --- a/debian/control +++ b/debian/control @@ -507,7 +507,7 @@ Description: log4qt interface Package: libukui-common0 Architecture: any -Depends: ${shlibs:Depends}, ${misc:Depends} +Depends: ${shlibs:Depends}, ${misc:Depends},libiniparser-dev Description: common module UKUI interface provides the interface for system configuration and related libraries. diff --git a/debian/libukui-common-dev.install b/debian/libukui-common-dev.install index 39cd608..92cadbb 100644 --- a/debian/libukui-common-dev.install +++ b/debian/libukui-common-dev.install @@ -1,4 +1,8 @@ -usr/include/ukuisdk/kylin-common.h -usr/lib/*/libukui-common.a -usr/lib/*/libukui-common.la -usr/lib/*/libukui-common.so +usr/include/ukuisdk/kylin-com4c.h +usr/include/ukuisdk/kylin-com4cxx.h +usr/lib/*/libukui-com4c.a +usr/lib/*/libukui-com4cxx.a +usr/lib/*/libukui-com4c.la +usr/lib/*/libukui-com4cxx.la +usr/lib/*/libukui-com4c.so +usr/lib/*/libukui-com4cxx.so diff --git a/debian/libukui-common0.install b/debian/libukui-common0.install index 7f02dfe..2b2a7ce 100644 --- a/debian/libukui-common0.install +++ b/debian/libukui-common0.install @@ -1 +1,2 @@ -usr/lib/*/libukui-common.so.* +usr/lib/*/libukui-com4c.so.* +usr/lib/*/libukui-com4cxx.so.* diff --git a/src/common/Makefile.am b/src/common/Makefile.am index 362ec5d..3a09c4a 100644 --- a/src/common/Makefile.am +++ b/src/common/Makefile.am @@ -1,21 +1,40 @@ #Generata binary file -lib_LTLIBRARIES = libukui-print.la libukui-gsettings.la libukui-common.la +lib_LTLIBRARIES = libukui-print.la libukui-gsettings.la libukui-com4c.la libukui-com4cxx.la #gcc -wall: displays all the errors and warning information when compiling #gcc -g: add the debugging code when compiling COMM_CFS = -Wall -g -#Add the dependent source file for libukui-common.la -libukui_common_la_SOURCES = kylin-common.c \ +#Add the dependent source file for libukui-com4c.la +libukui_com4c_la_SOURCES = kylin-com4c.c \ kylin-ini.c \ $(NULL) #Additional C compiler flags -libukui_common_la_CFLAGS= $(COMM_CFS) \ +libukui_com4c_la_CFLAGS= $(COMM_CFS) \ + -liniparser \ $(NULL) #Additional link objects -libukui_common_la_LDFLAGS= \ +libukui_com4c_la_LDFLAGS= \ + $(NULL) + +#Add the dependent source file for libukui-com4cxx.la +libukui_com4cxx_la_SOURCES = kylin-com4cxx.cpp \ + kylin-ini.c \ + $(NULL) + +#Additional CXX compiler flags +libukui_com4cxx_la_CXXFLAGS= $(COMM_CFS) \ + -liniparser \ + $(NULL) + +#Additional C compiler flags +libukui_com4cxx_la_CFLAGS= $(COMM_CFS) \ + $(NULL) + +#Additional link objects +libukui_com4cxx_la_LDFLAGS= \ $(NULL) #Add the dependent source file for libukui-print.la @@ -28,7 +47,8 @@ libukui_gsettings_la_SOURCES = kylin-gsettings-set.c \ #The header files that need to be installed include_HEADERS= \ - kylin-common.h \ + kylin-com4c.h \ + kylin-com4cxx.h \ kylin-print.h \ kylin-gsettings-set.h \ $(NULL) diff --git a/src/common/kylin-com4c.c b/src/common/kylin-com4c.c new file mode 100644 index 0000000..ef744c2 --- /dev/null +++ b/src/common/kylin-com4c.c @@ -0,0 +1,220 @@ +/* + * Copyright (C) 2021 Tianjin KYLIN Information Technology Co., Ltd. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see +#include +#include +#include +#include + +#include "kylin-ini.h" + +#define LSB_RELEASE_FILE "/etc/lsb-release" /* lsb-release文件路径 */ +#define OS_RELEASE_FILE "/etc/os-release" /* os-release文件路径 */ +#define KYINFO_FILE "/etc/.kyinfo" /* kyinfo文件路径 */ +#define CPUINFO_FILE "/proc/cpuinfo" /* cpuinfo文件路径 */ +#define RELEASEFILE_LINE_MAX 256 /* 最大解析行行数 */ +#define RELEASEFILE_LINE_MAX_LEN 256 /* 最大解析行长度 */ +#define RELEASEFILE_KEY_MAX_LEN 128 /* 最大key长度 */ +#define RELEASEFILE_VALUE_MAX_LEN 256 /* 最大value长度 预留'\0', '='*/ +#define RELEASEFILE_SPLIT_EQUAL '=' /* key和value的分隔符 */ +#define RELEASEFILE_SPLIT_COLON ':' /* key和value的分隔符 */ +#define PROJECT_CODENAME "PROJECT_CODENAME" +#define CPUINFO_MODELNAME "model name" + +// 根据key获取value,成功返回 >0 否则 返回 <= 0 +static int file_get_keyvalue(const char *path, const char *key, char *value, int value_max_len, const char chSplit) +{ + if (path == NULL || key == NULL || value == NULL || value_max_len <= 0) { + return -1; + } + int ret = 0; + int cnt = 0; + int key_len = 0; + int line_len = 0; + int value_len = 0; + FILE *fp = NULL; + char line_buf[RELEASEFILE_LINE_MAX_LEN] = {0}; + + /* 合法性判断 */ + if (NULL == path || NULL == key || NULL == value || 0 >= value_max_len) { + return -1; + } + + key_len = strlen(key); + if (0 >= key_len || RELEASEFILE_KEY_MAX_LEN < key_len) { + return -2; + } + + if (F_OK != access(path, F_OK)) { + return -3; + } + + /* 打开文件 */ + fp = fopen(path, "r"); + if (NULL == fp) { + return -4; + } + + /* 遍历行,匹配Key */ + while(NULL != fgets(line_buf, RELEASEFILE_LINE_MAX_LEN-1, fp)) { + line_len = strlen(line_buf); + if (line_len > key_len) { + /* 找到key */ + //找到非空格的首字符 + char *pStart = line_buf; + int nSplitIndex = 0; + while(pStart != (line_buf+line_len) && isspace(*pStart)) { + ++pStart; ++nSplitIndex; + } + if (0 == strncmp(pStart, key, key_len)) { + pStart = pStart + key_len; + nSplitIndex = nSplitIndex + key_len; + //跳过空格字符 + while(pStart != (line_buf+line_len) && isspace(*pStart)) { + ++pStart; ++nSplitIndex; + } + if (pStart != (line_buf+line_len) && *pStart == chSplit) { + ret = 1; + key_len = nSplitIndex; + break; + } + } + } + memset(line_buf, 0, sizeof(line_buf)); + + /* 最大查找行限制 */ + cnt++; + if (RELEASEFILE_LINE_MAX < cnt) { + break; + } + } + + /* 关闭文件 */ + fclose(fp); + fp = NULL; + + /* 找到key,返回value */ + if (1 == ret) { + value_len = line_len - key_len - 1; + if (0 < value_len) { + if (value_len > value_max_len) { + value_len = value_max_len; + } + /* 拷贝value */ + snprintf(value, value_max_len, "%s", &line_buf[key_len + 1]); + value[value_len] = '\0'; + + /* 去掉结尾的换行符 */ + strstrip(value, 1); + } else { + value[0] = '\0'; + } + } + return ret; +} + +/** + * @fn kdk_get_xdgsessiontype + * @brief 获取区分x11与wayland的环境变量值 + * @retval char* !NULL 成功 否则失败 + */ +char* kdk_get_xdgsessiontype() +{ + return getenv("XDG_SESSION_TYPE"); +} + +int kdk_get_lsbrelease(const char *key, char *value, int value_max_len) +{ + int nRet = -1; + if (NULL == key || NULL == value || 0 >= value_max_len) + return nRet; + dictionary *iniHandle = iniparser_load(LSB_RELEASE_FILE); + if (iniHandle) { + char sessionKey[256] = {0}; + snprintf(sessionKey, 256, ":%s", key); + const char *tempValue = iniparser_getstring(iniHandle, sessionKey, ""); + snprintf(value, value_max_len, "%s", tempValue); + iniparser_freedict(iniHandle); + iniHandle = NULL; + nRet = strlen(value); + } + return nRet; +} + +int kdk_get_osrelease(const char *key, char *value, int value_max_len) +{ + int nRet = -1; + if (NULL == key || NULL == value || 0 >= value_max_len) + return nRet; + dictionary *iniHandle = iniparser_load(OS_RELEASE_FILE); + if (iniHandle) { + char sessionKey[256] = {0}; + snprintf(sessionKey, 256, ":%s", key); + const char *tempValue = iniparser_getstring(iniHandle, sessionKey, ""); + snprintf(value, value_max_len, "%s", tempValue); + iniparser_freedict(iniHandle); + iniHandle = NULL; + nRet = strlen(value); + } + return nRet; +} + +int kdk_get_prjcodename(char *value, int value_max_len) +{ + int nResult = kdk_get_lsbrelease(PROJECT_CODENAME, value, value_max_len); + if (nResult <= 0) { + nResult = kdk_get_osrelease(PROJECT_CODENAME, value, value_max_len); + } + return nResult; +} + +int kdk_get_kyinfo(const char *session, const char *key, char *value, int value_max_len) +{ + int nRet = -1; + if (NULL == session || NULL == key || NULL == value || 0 >= value_max_len) + return nRet; + dictionary *iniHandle = iniparser_load(KYINFO_FILE); + if (iniHandle) { + char sessionKey[256] = {0}; + snprintf(sessionKey, 256, "%s:%s", session, key); + const char *tempValue = iniparser_getstring(iniHandle, sessionKey, ""); + snprintf(value, value_max_len, "%s", tempValue); + iniparser_freedict(iniHandle); + iniHandle = NULL; + nRet = strlen(value); + } + return nRet; +} + +int kdk_get_cpumodelname(char *modelName, int max_len) +{ + return file_get_keyvalue(CPUINFO_FILE, CPUINFO_MODELNAME, modelName, max_len, RELEASEFILE_SPLIT_COLON); +} + +int kdk_get_spechdplatform(char *platformName, int max_len) +{ + if (platformName == NULL || max_len <= 0) + return -1; + char strDefault[128] = "default"; + int validLen = strlen(strDefault); + validLen = validLen > max_len ? max_len : validLen; + snprintf(platformName, max_len, "%s", strDefault); + return validLen; +} \ No newline at end of file diff --git a/src/common/kylin-com4c.h b/src/common/kylin-com4c.h new file mode 100644 index 0000000..f890120 --- /dev/null +++ b/src/common/kylin-com4c.h @@ -0,0 +1,90 @@ +/* + * Copyright (C) 2021 Tianjin KYLIN Information Technology Co., Ltd. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @fn kdk_get_lsbrelease + * @brief 根据lsbrelease信息的键获取值 + * @param[in] key lsbrelease信息的键 + * @param[out] value lsbrelease信息的值 + * @param[in] value_max_len 值缓存区的大小 + * @retval int > 0 成功 否则失败 + */ +int kdk_get_lsbrelease(const char *key, char *value, int value_max_len); + +/** + * @fn kdk_get_osrelease + * @brief 根据osrelease信息的键获取值 + * @param[in] key osrelease信息的键 + * @param[out] value osrelease信息的值 + * @param[in] value_max_len 值缓存区的大小 + * @retval int > 0 成功 否则失败 + */ +int kdk_get_osrelease(const char *key, char *value, int value_max_len); + +/** + * @fn kdk_get_kyinfo + * @brief 根据kyinfo的键获取值 + * @param[in] session kyinfo的session值 + * @param[in] key kyinfo的键 + * @param[out] value kyinfo的值 + * @param[in] value_max_len 值缓存区的大小 + * @retval int >= 0 成功 否则失败 + */ +int kdk_get_kyinfo(const char *session, const char *key, char *value, int value_max_len); + +/** + * @fn kdk_get_prjcodename + * @brief 根据PROJECT_CODENAME字段的值 + * @param[out] value PROJECT_CODENAME字段的值 + * @param[in] value_max_len 值缓存区的大小 + * @retval int > 0 成功 否则失败 + */ +int kdk_get_prjcodename(char *value, int value_max_len); + +/** + * @fn kdk_get_cpumodelname + * @brief 获取CPU型号 + * @param[out] modelName CPU型号信息 + * @param[in] max_len CPU型号缓存区的大小 + * @retval int > 0 成功 否则失败 + */ +int kdk_get_cpumodelname(char *modelName, int max_len); + +/** + * @fn kdk_get_spechdplatform + * @brief 获取特定硬件平台信息 + * @param[out] platformName 特定硬件平台信息 + * @param[in] max_len 特定硬件平台缓存区的大小 + * @retval int > 0 成功 否则失败 + */ +int kdk_get_spechdplatform(char *platformName, int max_len); + +#ifdef __cplusplus +} +#endif + +#endif // __KYLINCOMM4C_H__ \ No newline at end of file diff --git a/src/common/kylin-common.c b/src/common/kylin-com4cxx.cpp similarity index 62% rename from src/common/kylin-common.c rename to src/common/kylin-com4cxx.cpp index 856e334..6cbe950 100644 --- a/src/common/kylin-common.c +++ b/src/common/kylin-com4cxx.cpp @@ -16,11 +16,12 @@ * */ -#include "kylin-common.h" +#include "kylin-com4cxx.h" #include #include #include #include +#include #include "kylin-ini.h" @@ -30,13 +31,13 @@ #define CPUINFO_FILE "/proc/cpuinfo" /* cpuinfo文件路径 */ #define RELEASEFILE_LINE_MAX 256 /* 最大解析行行数 */ #define RELEASEFILE_LINE_MAX_LEN 256 /* 最大解析行长度 */ -#define RELEASEFILE_KEY_MAX_LEN 64 /* 最大key长度 */ +#define RELEASEFILE_KEY_MAX_LEN 128 /* 最大key长度 */ #define RELEASEFILE_VALUE_MAX_LEN 256 /* 最大value长度 预留'\0', '='*/ -#define RELEASEFILE_SPLIT_CHAR '=' /* key和value的分隔符 */ +#define RELEASEFILE_SPLIT_EQUAL '=' /* key和value的分隔符 */ +#define RELEASEFILE_SPLIT_COLON ':' /* key和value的分隔符 */ #define PROJECT_CODENAME "PROJECT_CODENAME" #define CPUINFO_MODELNAME "model name" - // 根据key获取value,成功返回 >0 否则 返回 <= 0 static int file_get_keyvalue(const char *path, const char *key, char *value, int value_max_len, const char chSplit) { @@ -117,11 +118,11 @@ static int file_get_keyvalue(const char *path, const char *key, char *value, int value_len = value_max_len; } /* 拷贝value */ - strncpy(value, &line_buf[key_len + 1], value_len); + snprintf(value, value_max_len, "%s", &line_buf[key_len + 1]); value[value_len] = '\0'; /* 去掉结尾的换行符 */ - trim(value, 1); + strstrip(value, 1); } else { value[0] = '\0'; } @@ -129,55 +130,94 @@ static int file_get_keyvalue(const char *path, const char *key, char *value, int return ret; } -int common_get_xdgsessiontype(char *xdgSessionType, int max_len) +/** + * @fn KDKGetXdgSessionType + * @brief 获取区分x11与wayland的环境变量值 + * @param None 无参 + * @retval string xdg会话类型字符串,empty 失败,否则成功 + */ +string KDKGetXdgSessionType() { - if (xdgSessionType == NULL || max_len <= 0) - return -1; char *strSessionType = getenv("XDG_SESSION_TYPE"); if (!strSessionType) { - return -2; + return ""; } - unsigned int nValidLen = max_len < strlen(strSessionType) ? max_len: strlen(strSessionType); - memcpy(xdgSessionType, strSessionType, nValidLen*sizeof(char)); - return nValidLen; + return string(strSessionType); } -int common_get_lsbrelease(const char *key, char *value, int value_max_len) +string KDKGetLSBRelease(const string key) { - return file_get_keyvalue(LSB_RELEASE_FILE, key, value, value_max_len, RELEASEFILE_SPLIT_CHAR); + if (key.empty()) { + return ""; + } + dictionary *iniHandle = iniparser_load(LSB_RELEASE_FILE); + if (iniHandle) { + string sessionKey = ":"+key; + string strValue = ""; + strValue = iniparser_getstring(iniHandle, sessionKey.c_str(), ""); + iniparser_freedict(iniHandle); + iniHandle = NULL; + return strValue; + } + return ""; } -int common_get_osrelease(const char *key, char *value, int value_max_len) +string KDKGetOSRelease(const string key) { - return file_get_keyvalue(OS_RELEASE_FILE, key, value, value_max_len, RELEASEFILE_SPLIT_CHAR); + if (key.empty()) { + return ""; + } + dictionary *iniHandle = iniparser_load(OS_RELEASE_FILE); + if (iniHandle) { + string sessionKey = ":"+key; + string strValue = ""; + strValue = iniparser_getstring(iniHandle, sessionKey.c_str(), ""); + iniparser_freedict(iniHandle); + iniHandle = NULL; + return strValue; + } + return ""; } -int common_get_prjcodename(char *value, int value_max_len) +string KDKGetPrjCodeName() { - int nResult = common_get_lsbrelease(PROJECT_CODENAME, value, value_max_len); - if (nResult <= 0) { - nResult = common_get_osrelease(PROJECT_CODENAME, value, value_max_len); + string strValue = KDKGetLSBRelease(PROJECT_CODENAME); + if (strValue.empty()) { + strValue = KDKGetOSRelease(PROJECT_CODENAME); } - return nResult; + return strValue; } -int common_get_kyinfo(const char *session, const char *key, char *value, int value_max_len) +string KDKGetKYInfo(const string session, const string key) { - return getIniKeyString(KYINFO_FILE, session, key, value, value_max_len); + if (session.empty() || key.empty()) { + return ""; + } + dictionary *iniHandle = iniparser_load(KYINFO_FILE); + if (iniHandle) { + string sessionKey = session+":"+key; + string strValue = ""; + strValue = iniparser_getstring(iniHandle, sessionKey.c_str(), ""); + iniparser_freedict(iniHandle); + iniHandle = NULL; + return strValue; + } + return ""; } -int common_get_cpumodelname(char *modelName, int max_len) +string KDKGetCpuModelName() { - return file_get_keyvalue(CPUINFO_FILE, CPUINFO_MODELNAME, modelName, max_len, ':'); + char strValue[256] = {0}; + int nRet = file_get_keyvalue(CPUINFO_FILE, CPUINFO_MODELNAME, strValue, 256, RELEASEFILE_SPLIT_COLON); + if (nRet > 0) { + return string(strValue); + } else { + return ""; + } } -int common_get_spechdplatform(char *platformName, int max_len) +string KDKGetSpecHDPlatform() { - if (platformName == NULL || max_len <= 0) - return -1; - char strDefault[] = "default"; - int validLen = strlen(strDefault); - validLen = validLen > max_len ? max_len : validLen; - strncpy(platformName, strDefault, validLen); - return validLen; + string strDefaultValue = "default"; + return strDefaultValue; } \ No newline at end of file diff --git a/src/common/kylin-com4cxx.h b/src/common/kylin-com4cxx.h new file mode 100644 index 0000000..c3ac8f3 --- /dev/null +++ b/src/common/kylin-com4cxx.h @@ -0,0 +1,84 @@ +/* + * Copyright (C) 2021 Tianjin KYLIN Information Technology Co., Ltd. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see +using namespace std; + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @fn KDKGetLsbRelease + * @brief 根据lsbrelease信息的键获取值 + * @param[in] key lsbrelease信息的键 + * @param[out] value lsbrelease信息的值 + * @param[in] value_max_len 值缓存区的大小 + * @retval string lsbrelease信息的值,empty 失败,否则成功 + */ +string KDKGetLSBRelease(const string key); + +/** + * @fn KDKGetOSRelease + * @brief 根据osrelease信息的键获取值 + * @param[in] key osrelease信息的键 + * @retval string osrelease信息的值,empty 失败,否则成功 + */ +string KDKGetOSRelease(const string key); + +/** + * @fn KDKGetKYInfo + * @brief 根据kyinfo的键获取值 + * @param[in] session kyinfo的session值 + * @param[in] key kyinfo的键 + * @retval string kyinfo信息的键值,empty 失败,否则成功 + */ +string KDKGetKYInfo(const string session, const string key); + +/** + * @fn KDKGetPrjCodeName + * @brief 根据PROJECT_CODENAME字段的值 + * @param None 无参 + * @retval string PROJECT_CODENAME字段的值,empty 失败,否则成功 + */ +string KDKGetPrjCodeName(); + +/** + * @fn KDKGetCpuModelName + * @brief 获取CPU型号 + * @param None 无参 + * @retval string CPU型号信息,empty 失败,否则成功 + */ +string KDKGetCpuModelName(); + +/** + * @fn KDKGetSpecHDPlatform + * @brief 获取特定硬件平台信息 + * @param None 无参 + * @retval string 特定硬件平台信息,empty 失败,否则成功 + */ +string KDKGetSpecHDPlatform(); + +#ifdef __cplusplus +} +#endif + +#endif // __KYLINCOMM4C_H__ \ No newline at end of file diff --git a/src/common/kylin-common.h b/src/common/kylin-common.h deleted file mode 100644 index 1ded6c6..0000000 --- a/src/common/kylin-common.h +++ /dev/null @@ -1,99 +0,0 @@ -/* - * Copyright (C) 2021 Tianjin KYLIN Information Technology Co., Ltd. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3, or (at your option) - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, see - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * 函数名称:common_get_xdgsessiontype - * 功能: 获取区分x11与wayland的环境变量值 - * 参数1:xdgSessionType xdg会话类型字符串指针(out) - * 参数2:max_len xdg会话类型字符串缓存大小(in) - * 返回值:> 0 成功 否则失败 - **/ -int common_get_xdgsessiontype(char *xdgSessionType, int max_len); - -/** - * 函数名称:common_get_lsbrelease - * 功能:根据lsbrelease信息的键获取值 - * 参数1:key lsbrelease信息的键(in) - * 参数2:value lsbrelease信息的值(out) - * 参数3:value_max_len 值缓存区的大小(in) - * 返回值:> 0 成功 否则失败 - **/ -int common_get_lsbrelease(const char *key, char *value, int value_max_len); - -/** - * 函数名称:common_get_osrelease - * 功能:根据osrelease信息的键获取值 - * 参数1:key osrelease信息的键(in) - * 参数2:value osrelease信息的值(out) - * 参数3:value_max_len 值缓存区的大小(in) - * 返回值:> 0 成功 否则失败 - **/ -int common_get_osrelease(const char *key, char *value, int value_max_len); - -/** - * 函数名称:common_get_kyinfo - * 功能:根据kyinfo的键获取值 - * 参数1:session kyinfo的session值(in) - * 参数2:key kyinfo的键(in) - * 参数3:value kyinfo的值(out) - * 参数4:value_max_len 值缓存区的大小(in) - * 返回值:>= 0 成功 否则失败 - **/ -int common_get_kyinfo(const char *session, const char *key, char *value, int value_max_len); - -/** - * 函数名称:common_get_prjcodename - * 功能:根据PROJECT_CODENAME字段的值 - * 参数1:value PROJECT_CODENAME字段的值(out) - * 参数2:value_max_len 值缓存区的大小(in) - * 返回值:> 0 成功 否则失败 - **/ -int common_get_prjcodename(char *value, int value_max_len); - -/** - * 函数名称:common_get_cpumodelname - * 功能:获取CPU型号 - * 参数1:modelName CPU型号信息(out) - * 参数2:max_len CPU型号缓存区的大小(in) - * 返回值:> 0 成功 否则失败 - **/ -int common_get_cpumodelname(char *modelName, int max_len); - -/** - * 函数名称:common_get_spechdplatform - * 功能:获取特定硬件平台信息 - * 参数1:platformName 特定硬件平台信息(out) - * 参数2:max_len 特定硬件平台缓存区的大小(in) - * 返回值:> 0 成功 否则失败 - **/ -int common_get_spechdplatform(char *platformName, int max_len); - -#ifdef __cplusplus -} -#endif - -#endif // __KYLINCOMMON_H__ \ No newline at end of file diff --git a/src/common/kylin-ini.c b/src/common/kylin-ini.c index 8ba3b88..3965919 100644 --- a/src/common/kylin-ini.c +++ b/src/common/kylin-ini.c @@ -34,7 +34,7 @@ '\r' (0x0d) carriage return (CR) 回车符 //windows \r\n linux \n mac \r */ -char *rtrim(char *str, int containQuot) +char *strstripr(char *str, int containQuot) { if(str == NULL || *str == '\0') { return str; @@ -54,7 +54,7 @@ char *rtrim(char *str, int containQuot) } //去除首部空格 -char *ltrim(char *str, int containQuot) +char *strstripl(char *str, int containQuot) { if(str == NULL || *str == '\0') { return str; @@ -75,112 +75,9 @@ char *ltrim(char *str, int containQuot) } //去除首尾空格 -char *trim(char *str, int containQuot) +char *strstrip(char *str, int containQuot) { - str = rtrim(str, containQuot); - str = ltrim(str, containQuot); + str = strstripr(str, containQuot); + str = strstripl(str, containQuot); return str; } - -// getIniKeyString 读取ini键值 -int getIniKeyString(const char *filename, const char *session, const char *key, char *value, int value_max_len) -{ - if (filename == NULL || session == NULL || key == NULL || value == NULL || value_max_len <= 0) - return -1; // 参数错误 - // 清空目标缓存 - FILE *fp = NULL; - int flag = 0; - char sSession[64], *wTmp = NULL; - char sLine[1024]; - snprintf(sSession, 64, "[%s]", session); - if(NULL == (fp = fopen(filename, "r"))) { - perror("fopen"); - return -1; - } - while (NULL != fgets(sLine, 1024, fp)) { - // 这是注释行 - trim(sLine, 0); - if (0 == strncmp("//", sLine, 2)) continue; - if ('#' == sLine[0]) continue; - wTmp = strchr(sLine, '='); - if ((NULL != wTmp) && (1 == flag)) { - int keyLen = wTmp - sLine; - char keyName[256] = {0}; - strncpy(keyName, sLine, keyLen); - rtrim(keyName, 0); - keyLen = strlen(keyName) > strlen(key) ? strlen(keyName) : strlen(key); - if (0 == strncmp(key, keyName, keyLen)) { // 长度依文件读取的为准 - fclose(fp); - int nValidLen = strlen(wTmp + 1); - nValidLen = nValidLen < value_max_len ? nValidLen : value_max_len; - strncpy(value, wTmp + 1, nValidLen); - trim(value, 1); - return 0; - } - } else { - if (0 == strncmp(sSession, sLine, strlen(sSession))) { // 长度依文件读取的为准 - flag = 1; // 找到目标session位置 - } else if (flag == 1) { // 找到其他空行或session - wTmp = strchr(sLine, '['); - if (NULL != wTmp) { - flag = 0; - } - } - } - } - fclose(fp); - return -1; -} - -// 设置ini键值 -int setIniKeyString(const char *filename, const char *session, const char *key, char *value) -{ - if (filename == NULL || session == NULL || key == NULL || value == NULL) - return -1; // 参数错误 - FILE *fpr = NULL, *fpw = NULL; - int flag = 0; - char sLine[1024] = {0}, sSession[64] = {0}, *wTmp = NULL; - snprintf(sSession, 64, "[%s]", session); - if (NULL == (fpr = fopen(filename, "r"))) - return -1;// 读取原文件 - - snprintf(sLine, 256, "%s.tmp", filename); - if (NULL == (fpw = fopen(sLine, "w"))) { - fclose(fpr); - fpr = NULL; - return -1;// 写入临时文件 - } - - while (NULL != fgets(sLine, 1024, fpr)) { - if (2 != flag) { // 如果找到要修改的那一行,则不会执行内部的操作 - wTmp = strchr(sLine, '='); - if ((NULL != wTmp) && (1 == flag)) { - if (0 == strncmp(key, sLine, strlen(key))) { // 长度依文件读取的为准 - flag = 2;// 更改值,方便写入文件 - snprintf(wTmp + 1, 256, " %s\n", value); - break; - } - } else { - if (0 == strncmp(sSession, sLine, strlen(sSession))) { // 长度依文件读取的为准 - flag = 1; // 找到标题位置 - } - } - } - fputs(sLine, fpw); // 写入临时文件 - } - if (flag == 0) { // 未找到session - char wBuffer[1024] = {0}; - snprintf(wBuffer, 1024, "%s\n", sSession); - fputs(wBuffer, fpw); // 写入会话 - snprintf(wBuffer, 1024, "%s = %s\n", key, value); - fputs(wBuffer, fpw); // 写入键值 - } else if (flag == 1) { // 待完善 - char wBuffer[1024] = {0}; - snprintf(wBuffer, 1024, "%s = %s\n", key, value); - fputs(wBuffer, fpw); // 写入键值 - } - fclose(fpr); - fclose(fpw); - snprintf(sLine, 256, "%s.tmp", filename); - return rename(sLine, filename);// 将临时文件更新到原文件 -} diff --git a/src/common/kylin-ini.h b/src/common/kylin-ini.h index 614f912..7cc94fd 100644 --- a/src/common/kylin-ini.h +++ b/src/common/kylin-ini.h @@ -22,17 +22,21 @@ #include #include +#ifdef __cplusplus +extern "C" { +#endif + // 去除尾部空格 -char *rtrim(char *str, int containQuot); +char *strstripr(char *str, int containQuot); // 去除头部空格 -char *ltrim(char *str, int containQuot); +char *strstripl(char *str, int containQuot); // 去除前后空格 -char *trim(char *str, int containQuot); - -int getIniKeyString(const char *filename, const char *session, const char *key, char *value, int value_max_len); +char *strstrip(char *str, int containQuot); -int setIniKeyString(const char *filename, const char *session, const char *key, char *value); +#ifdef __cplusplus +} +#endif #endif //__KYLININI_H__ \ No newline at end of file From 81b8d9ea7e5c165767a3ae1325c0019bcb711884 Mon Sep 17 00:00:00 2001 From: winnerym100 Date: Fri, 30 Jul 2021 15:52:35 +0800 Subject: [PATCH 25/35] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E7=BC=96=E5=8C=85?= =?UTF-8?q?=E9=94=99=E8=AF=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- debian/control | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/debian/control b/debian/control index ebfc7c9..c3f0791 100644 --- a/debian/control +++ b/debian/control @@ -10,7 +10,8 @@ Build-Depends: debhelper-compat (=12), libtool, qtbase5-dev, libgsettings-qt-dev, - qttools5-dev-tools + qttools5-dev-tools, + libiniparser-dev Standards-Version: 4.5.0 Rules-Requires-Root: no Homepage: https://github.com/ukui/ukui-interface @@ -507,7 +508,7 @@ Description: log4qt interface Package: libukui-common0 Architecture: any -Depends: ${shlibs:Depends}, ${misc:Depends},libiniparser-dev +Depends: ${shlibs:Depends}, ${misc:Depends} Description: common module UKUI interface provides the interface for system configuration and related libraries. From f01f1a2e81f4702ca077297f16650dbd8e74921b Mon Sep 17 00:00:00 2001 From: handsome-feng Date: Mon, 16 Aug 2021 21:35:27 +0800 Subject: [PATCH 26/35] Update changelog --- debian/changelog | 10 ++++------ debian/upstream/metadata | 2 ++ 2 files changed, 6 insertions(+), 6 deletions(-) create mode 100644 debian/upstream/metadata diff --git a/debian/changelog b/debian/changelog index af3f47e..6466cf4 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,15 +1,13 @@ -ukui-interface (1.0.2-1) experimental; urgency=medium +ukui-interface (1.0.1-1) unstable; urgency=medium + [ handsome_feng ] * New upstream release. - -- handsome_feng Thu, 29 Jul 2021 11:51:46 +0800 - -ukui-interface (1.0.0-2) unstable; urgency=low - + [ Debian Janior ] * Set upstream metadata fields: Bug-Database, Bug-Submit. * Update standards version to 4.5.0, no changes needed. - -- Debian Janitor Thu, 11 Jun 2020 02:24:40 -0000 + -- handsome_feng Thu, 29 Jul 2021 11:51:46 +0800 ukui-interface (1.0.0-1) unstable; urgency=medium diff --git a/debian/upstream/metadata b/debian/upstream/metadata new file mode 100644 index 0000000..a71fcf6 --- /dev/null +++ b/debian/upstream/metadata @@ -0,0 +1,2 @@ +Bug-Database: https://github.com/ukui/ukui-interface/issues +Bug-Submit: https://github.com/ukui/ukui-interface/issues/new From b1f614d0e3fd9fffe67ed828375447345bcfd8d7 Mon Sep 17 00:00:00 2001 From: handsome-feng Date: Tue, 17 Aug 2021 10:05:15 +0800 Subject: [PATCH 27/35] Add watch, update control --- debian/control | 2 -- debian/watch | 3 +++ 2 files changed, 3 insertions(+), 2 deletions(-) create mode 100644 debian/watch diff --git a/debian/control b/debian/control index c3f0791..ce1ceaa 100644 --- a/debian/control +++ b/debian/control @@ -486,8 +486,6 @@ Description: xkbgeneral settings service process Package: libukui-log4qt1 Architecture: any Depends: ${shlibs:Depends}, ${misc:Depends}, libglib2.0-bin -Suggests: libukui-log4qt0 -Replaces: libukui-log4qt0 Description: log4qt module UKUI interface provides the interface for system configuration and related libraries. diff --git a/debian/watch b/debian/watch new file mode 100644 index 0000000..a0d6f97 --- /dev/null +++ b/debian/watch @@ -0,0 +1,3 @@ +version=4 +opts=filenamemangle=s/.+\/v?(\d\S+)\.tar\.gz/ukui-interface-$1\.tar\.gz/ \ + https://github.com/ukui/ukui-interface/releases .*/v?(\d\S+)\.tar\.gz From b6322d2123e7a4f21cd61ac9cdc827d26dae20d0 Mon Sep 17 00:00:00 2001 From: handsome-feng Date: Tue, 17 Aug 2021 19:00:45 +0800 Subject: [PATCH 28/35] Drop debian/tests --- debian/changelog | 2 +- debian/tests/control | 3 --- debian/tests/testlog4qt.sh | 5 ----- 3 files changed, 1 insertion(+), 9 deletions(-) delete mode 100644 debian/tests/control delete mode 100755 debian/tests/testlog4qt.sh diff --git a/debian/changelog b/debian/changelog index 6466cf4..0aabbeb 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,4 +1,4 @@ -ukui-interface (1.0.1-1) unstable; urgency=medium +ukui-interface (1.0.1-2) unstable; urgency=medium [ handsome_feng ] * New upstream release. diff --git a/debian/tests/control b/debian/tests/control deleted file mode 100644 index d035d06..0000000 --- a/debian/tests/control +++ /dev/null @@ -1,3 +0,0 @@ -Test-Command: testlog4qt.sh -Depends: libukui-log4qt-dev -Restrictions: diff --git a/debian/tests/testlog4qt.sh b/debian/tests/testlog4qt.sh deleted file mode 100755 index 7d87530..0000000 --- a/debian/tests/testlog4qt.sh +++ /dev/null @@ -1,5 +0,0 @@ -#!/bin/sh - -if [ -f '/usr/lib/libukui-log4qt.so' ] then - exit 0 -fi From 40c50da28aac9b0e54abc5191c7f0b827313d2a1 Mon Sep 17 00:00:00 2001 From: winnerym100 Date: Tue, 19 Oct 2021 18:57:11 +0800 Subject: [PATCH 29/35] =?UTF-8?q?=E5=90=8C=E6=AD=A5master=E5=88=86?= =?UTF-8?q?=E6=94=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- debian/control | 2 ++ 1 file changed, 2 insertions(+) diff --git a/debian/control b/debian/control index ce1ceaa..c3f0791 100644 --- a/debian/control +++ b/debian/control @@ -486,6 +486,8 @@ Description: xkbgeneral settings service process Package: libukui-log4qt1 Architecture: any Depends: ${shlibs:Depends}, ${misc:Depends}, libglib2.0-bin +Suggests: libukui-log4qt0 +Replaces: libukui-log4qt0 Description: log4qt module UKUI interface provides the interface for system configuration and related libraries. From d95b88ea934297f30d44d6804d9f152895e1557b Mon Sep 17 00:00:00 2001 From: handsome-feng Date: Fri, 29 Oct 2021 11:25:26 +0800 Subject: [PATCH 30/35] =?UTF-8?q?Revert=20"=E5=90=8C=E6=AD=A5master?= =?UTF-8?q?=E5=88=86=E6=94=AF"?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This reverts commit 40c50da28aac9b0e54abc5191c7f0b827313d2a1. --- debian/control | 2 -- 1 file changed, 2 deletions(-) diff --git a/debian/control b/debian/control index c3f0791..ce1ceaa 100644 --- a/debian/control +++ b/debian/control @@ -486,8 +486,6 @@ Description: xkbgeneral settings service process Package: libukui-log4qt1 Architecture: any Depends: ${shlibs:Depends}, ${misc:Depends}, libglib2.0-bin -Suggests: libukui-log4qt0 -Replaces: libukui-log4qt0 Description: log4qt module UKUI interface provides the interface for system configuration and related libraries. From f8bd236bc1d88d6f6383910989a9503e423b857f Mon Sep 17 00:00:00 2001 From: handsome-feng Date: Fri, 29 Oct 2021 17:20:19 +0800 Subject: [PATCH 31/35] Update copyright and watch file --- debian/copyright | 212 ++++------------------------------------------- debian/watch | 3 +- 2 files changed, 17 insertions(+), 198 deletions(-) diff --git a/debian/copyright b/debian/copyright index d20d038..7e07100 100644 --- a/debian/copyright +++ b/debian/copyright @@ -5,129 +5,36 @@ Source: https://github.com/ukui/ukui-interface Files: * Copyright: 2019, Tianjin KYLIN Information Technology Co., Ltd. -License: GPL-3.0+ +License: GPL-3+ Files: debian/* Copyright: 2019, liuhao -License: GPL-3.0+ - -Files: po/Makevars -Copyright: for their translations to this person -License: GPL-3.0+ - -Files: src/accounts/user/* -Copyright: 2019, 2021, Tianjin KYLIN Information Technology Co., Ltd. + 2021, handsome_feng License: GPL-3+ -Files: src/accounts/user/Makefile.am -Copyright: 2019, Tianjin KYLIN Information Technology Co., Ltd. -License: GPL-3.0+ - -Files: src/common/* -Copyright: 2019, 2021, Tianjin KYLIN Information Technology Co., Ltd. -License: GPL-3+ - -Files: src/common/Makefile.am -Copyright: 2019, Tianjin KYLIN Information Technology Co., Ltd. -License: GPL-3.0+ - -Files: src/date/dttm/* -Copyright: 2019, 2021, Tianjin KYLIN Information Technology Co., Ltd. -License: GPL-3+ - -Files: src/date/dttm/Makefile.am -Copyright: 2019, Tianjin KYLIN Information Technology Co., Ltd. -License: GPL-3.0+ - -Files: src/hardware/* -Copyright: 2019, 2021, Tianjin KYLIN Information Technology Co., Ltd. -License: GPL-3+ - -Files: src/hardware/Makefile.am -Copyright: 2019, Tianjin KYLIN Information Technology Co., Ltd. -License: GPL-3.0+ - -Files: src/hardware/keyboard/Makefile.am -Copyright: 2019, Tianjin KYLIN Information Technology Co., Ltd. -License: GPL-3.0+ - -Files: src/hardware/mouse/Makefile.am -Copyright: 2019, Tianjin KYLIN Information Technology Co., Ltd. -License: GPL-3.0+ - -Files: src/hardware/power/Makefile.am -Copyright: 2019, Tianjin KYLIN Information Technology Co., Ltd. -License: GPL-3.0+ - -Files: src/hardware/touchpad/Makefile.am -Copyright: 2019, Tianjin KYLIN Information Technology Co., Ltd. -License: GPL-3.0+ - -Files: src/log4qt/* -Copyright: 2019, 2021, Tianjin KYLIN Information Technology Co., Ltd. -License: GPL-3+ - -Files: src/log4qt/Doxyfile -Copyright: 2019, Tianjin KYLIN Information Technology Co., Ltd. -License: GPL-3.0+ - Files: src/log4qt/doc/* + src/log4qt/tests/* + src/log4qt/log4qt/* Copyright: 2007 - 2009 Martin Heinrich License: Apache-2.0 - 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. - . - On Debian systems, the complete text of the Apache License Version 2.0 - can be found in `/usr/share/common-licenses/Apache-2.0'. - -Files: src/log4qt/log4qt/* -Copyright: 2007-2009, Martin Heinrich -License: Apache-2.0 - 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. - . - On Debian systems, the complete text of the Apache License Version 2.0 - can be found in `/usr/share/common-licenses/Apache-2.0'. -Files: src/log4qt/log4qt/helpers/asyncdispatcher.cpp - src/log4qt/log4qt/helpers/asyncdispatcher.h -Copyright: 2019, 2021, Tianjin KYLIN Information Technology Co., Ltd. License: GPL-3+ - 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 + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. . - http://www.apache.org/licenses/LICENSE-2.0 + This package is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. . - 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. + You should have received a copy of the GNU General Public License + along with this program. If not, see . . - On Debian systems, the complete text of the Apache License Version 2.0 - can be found in `/usr/share/common-licenses/Apache-2.0'. + On Debian systems, the complete text of the GNU General + Public License version 3 can be found in "/usr/share/common-licenses/GPL-3". -Files: src/log4qt/tests/* -Copyright: 2007-2009, Martin Heinrich License: Apache-2.0 Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -143,90 +50,3 @@ License: Apache-2.0 . On Debian systems, the complete text of the Apache License Version 2.0 can be found in `/usr/share/common-licenses/Apache-2.0'. - -Files: src/network/network/* -Copyright: 2019, 2021, Tianjin KYLIN Information Technology Co., Ltd. -License: GPL-3+ - -Files: src/network/network/Makefile.am -Copyright: 2019, Tianjin KYLIN Information Technology Co., Ltd. -License: GPL-3.0+ - -Files: src/os/* -Copyright: 2019, 2021, Tianjin KYLIN Information Technology Co., Ltd. -License: GPL-3+ - -Files: src/os/Makefile.am -Copyright: 2019, Tianjin KYLIN Information Technology Co., Ltd. -License: GPL-3.0+ - -Files: src/os/subversion/Makefile.am -Copyright: 2019, Tianjin KYLIN Information Technology Co., Ltd. -License: GPL-3.0+ - -Files: src/os/sysinfo/Makefile.am -Copyright: 2019, Tianjin KYLIN Information Technology Co., Ltd. -License: GPL-3.0+ - -Files: src/personal/* -Copyright: 2019, 2021, Tianjin KYLIN Information Technology Co., Ltd. -License: GPL-3+ - -Files: src/personal/Makefile.am -Copyright: 2019, Tianjin KYLIN Information Technology Co., Ltd. -License: GPL-3.0+ - -Files: src/personal/background/Makefile.am -Copyright: 2019, Tianjin KYLIN Information Technology Co., Ltd. -License: GPL-3.0+ - -Files: src/personal/desktop/Makefile.am -Copyright: 2019, Tianjin KYLIN Information Technology Co., Ltd. -License: GPL-3.0+ - -Files: src/personal/font/Makefile.am -Copyright: 2019, Tianjin KYLIN Information Technology Co., Ltd. -License: GPL-3.0+ - -Files: src/personal/marcogeneral/Makefile.am -Copyright: 2019, Tianjin KYLIN Information Technology Co., Ltd. -License: GPL-3.0+ - -Files: src/software/defaultprograms/* -Copyright: 2019, 2021, Tianjin KYLIN Information Technology Co., Ltd. -License: GPL-3+ - -Files: src/software/defaultprograms/Makefile.am -Copyright: 2019, Tianjin KYLIN Information Technology Co., Ltd. -License: GPL-3.0+ - -License: GPL-3+ - This software is Copyright (c) 2021 by X. Ample. - . - This is free software, licensed under: - . - The GNU General Public License, Version 3, June 2007 - . - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; version 3 dated June, 2007, or (at - your option) any later version. - On Debian systems, the complete text of version 3 of the GNU General - Public License can be found in '/usr/share/common-licenses/GPL-3'. - -License: GPL-3.0+ - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - . - This package is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - . - You should have received a copy of the GNU General Public License - along with this program. If not, see . - . - On Debian systems, the complete text of the GNU General - Public License version 3 can be found in "/usr/share/common-licenses/GPL-3". diff --git a/debian/watch b/debian/watch index a0d6f97..dd56e12 100644 --- a/debian/watch +++ b/debian/watch @@ -1,3 +1,2 @@ version=4 -opts=filenamemangle=s/.+\/v?(\d\S+)\.tar\.gz/ukui-interface-$1\.tar\.gz/ \ - https://github.com/ukui/ukui-interface/releases .*/v?(\d\S+)\.tar\.gz +https://github.com/ukui/ukui-interface/releases .*/ukui-interface_(\d\S+)\.orig\.tar\.gz From 82e1aabd4a5ed735d725911ab172577a61e6666e Mon Sep 17 00:00:00 2001 From: handsome-feng Date: Fri, 29 Oct 2021 18:05:43 +0800 Subject: [PATCH 32/35] Update changelog --- debian/changelog | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/debian/changelog b/debian/changelog index 0aabbeb..63d5b48 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,13 +1,14 @@ -ukui-interface (1.0.1-2) unstable; urgency=medium +ukui-interface (1.0.1-1) unstable; urgency=medium [ handsome_feng ] * New upstream release. + * debian: update copyright and watch. [ Debian Janior ] * Set upstream metadata fields: Bug-Database, Bug-Submit. * Update standards version to 4.5.0, no changes needed. - -- handsome_feng Thu, 29 Jul 2021 11:51:46 +0800 + -- handsome_feng Fri, 29 Oct 2021 17:17:52 +0800 ukui-interface (1.0.0-1) unstable; urgency=medium From f46e2e4c5fd49c59c657b676c0f10fdb807142f4 Mon Sep 17 00:00:00 2001 From: handsome-feng Date: Tue, 2 Nov 2021 14:55:06 +0800 Subject: [PATCH 33/35] Update changelog for source only upload --- debian/changelog | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/debian/changelog b/debian/changelog index 63d5b48..d6b5401 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,9 @@ +ukui-interface (1.0.1-2) unstable; urgency=medium + + * Source only upload for migration to testing. + + -- handsome_feng Tue, 02 Nov 2021 14:53:40 +0800 + ukui-interface (1.0.1-1) unstable; urgency=medium [ handsome_feng ] From 40bfab3ceb1fce8be0240f708a4dbcbc06b0ef69 Mon Sep 17 00:00:00 2001 From: handsome-feng Date: Tue, 9 Nov 2021 19:41:01 +0800 Subject: [PATCH 34/35] Break and replace libukui-log4qt0 --- debian/control | 2 ++ 1 file changed, 2 insertions(+) diff --git a/debian/control b/debian/control index ce1ceaa..0b14948 100644 --- a/debian/control +++ b/debian/control @@ -486,6 +486,8 @@ Description: xkbgeneral settings service process Package: libukui-log4qt1 Architecture: any Depends: ${shlibs:Depends}, ${misc:Depends}, libglib2.0-bin +Breaks: libukui-log4qt0 +Replaces: libukui-log4qt0 Description: log4qt module UKUI interface provides the interface for system configuration and related libraries. From 9308f5f54e233e1ee148f2e8f1b7702425125855 Mon Sep 17 00:00:00 2001 From: Debian Janitor Date: Thu, 9 Mar 2023 08:30:50 +0000 Subject: [PATCH 35/35] Apply multi-arch hints. + libukui-common0, libukui-gsettings0, libukui-network0, libukui-print0, libukui-usersetting0: Add Multi-Arch: same. Changes-By: apply-multiarch-hints --- debian/control | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/debian/control b/debian/control index 0b14948..66b0fde 100644 --- a/debian/control +++ b/debian/control @@ -21,6 +21,7 @@ Vcs-Git: https://github.com/ukui/ukui-interface.git Package: libukui-print0 Architecture: any Depends: ${shlibs:Depends}, ${misc:Depends} +Multi-Arch: same Description: print module UKUI interface provides the interface for system configuration and related libraries. @@ -41,6 +42,7 @@ Description: print interface Package: libukui-gsettings0 Architecture: any Depends: ${shlibs:Depends}, ${misc:Depends} +Multi-Arch: same Description: application settings module UKUI interface provides the interface for system configuration and related libraries. @@ -303,6 +305,7 @@ Description: mouse settings interfaces Package: libukui-network0 Architecture: any Depends: ${shlibs:Depends}, ${misc:Depends} +Multi-Arch: same Description: network settings module UKUI interface provides the interface for system configuration and related libraries. @@ -457,6 +460,7 @@ Description: touchpad settings interfaces Package: libukui-usersetting0 Architecture: any Depends: ${shlibs:Depends}, ${misc:Depends} +Multi-Arch: same Description: user settings module UKUI interface provides the interface for system configuration and related libraries. @@ -509,6 +513,7 @@ Description: log4qt interface Package: libukui-common0 Architecture: any Depends: ${shlibs:Depends}, ${misc:Depends} +Multi-Arch: same Description: common module UKUI interface provides the interface for system configuration and related libraries.