apache / logging-log4cxx

Apache Log4cxx is a C++ port of Apache Log4j
http://logging.apache.org/log4cxx
Apache License 2.0
278 stars 122 forks source link

CustomAppender Example - Class Not Found #391

Closed sylphrena0 closed 4 months ago

sylphrena0 commented 4 months ago

I'm attempting to create a custom layout to support RFC5424 (see #390), however, I receive a class not found error after compiling my layout and attempting to load the configuration. I attempted to replicate the example extension provided by documentation. However, after adding using namespace log4cxx to resolve the compiler errors with the code, I receive the following error:

log4cxx: Could not create an Appender. Reported error follows.
log4cxx: Class not found: NullWriterAppender
log4cxx: No appender named [NullAppender] could be found.
Segmentation fault

I copied custom-appender.cpp verbatim, and copied the appender and appender-ref to my configuration file.

Any guidance or suggestions would be appreciated.

I am using Clang 14.0.6 x86_64-pc-linux-gnu

rm5248 commented 4 months ago

Probably the issue is that your naming is incorrect.

The macro DECLARE_LOG4CXX_OBJECT(NullWriterAppender) maps to the name of the class, and it is this name(NullWriterAppender) that is used to load the class.

The code and config file go together, so they need to look something like this:

class MyAppender : public AppenderSkeleton {
public:
    DECLARE_LOG4CXX_OBJECT(MyAppender)
...
};

In the XML file:
  <appender name="some-name-here" class="MyAppender">
  </appender>

Note that the appender does not need to be in the log4cxx namespace at all.

sylphrena0 commented 4 months ago

I am using the configuration from the example, so the naming is correct. For the example, the macro is IMPLEMENT_LOG4CXX_OBJECT(NullWriterAppender) and the xml is:

  <appender
    name="NullAppender"
    class="NullWriterAppender">
    <param
      name="SomeValue"
      value="Nothing" />
  </appender>
  <root>
    <priority value="info" />
    <appender-ref ref="NullAppender" />
  </root>

Does the namespace need to be included in the classname, if the custom class is defined outside of the root namespace (I have attempted this with no luck)? Is the something particular I need to do with cmake that may be causing the class not found issue?

rm5248 commented 4 months ago

If you've tried that, the only other thing that I can think of is that the class might not be registering properly with log4cxx - this depends slightly on how log4cxx is built/the compiler.

You can try registering the class manually, call the NullWriterAppender::registerClass() method directly and then try loading your config file.

If that doesn't work, a minimal complete example would be helpful in order to debug what is going on.

swebb2066 commented 4 months ago

The example custom-appender is build by the Log4cxx build scripts (unless you define BUILD_TESTING=off). Please try running that program by doing:

$ ( cd /home/steph/logging-log4cxx/src/examples/cpp/; LOG4CXX_DEBUG=true /home/steph/logging-log4cxx/build/src/examples/cpp/custom-appender.exe )

The output should be:

log4cxx: Started
log4cxx: DOMConfigurator configuring file custom-appender.xml...
log4cxx: Loading configuration file [custom-appender.xml].
log4cxx: debug attribute= "".
log4cxx: Ignoring internalDebug attribute.
log4cxx: Threshold ="".
log4cxx: Level value for root is [info].
log4cxx: OptionConverter::toLevel: no class name specified, level=[info]
log4cxx: root level set to INFO
log4cxx: Class name: [org.apache.log4j.ConsoleAppender]
log4cxx: Setting option name=[Target], value=[System.out]
log4cxx: Parsing layout of class: "org.apache.log4j.PatternLayout"
log4cxx: Setting option name=[ConversionPattern], value=[[%d{yyyy-MM-dd HH:mm:ss}] %c %-5p - %m%n]
log4cxx: Adding appender named [ConsoleAppender] to logger [root].
log4cxx: Retreiving an instance of NullLogger
log4cxx: Setting [NullLogger] additivity to [false].
log4cxx: Class name: [NullWriterAppender]
log4cxx: Setting option name=[SomeValue], value=[Nothing]
log4cxx: Adding appender named [NullAppender] to logger [NullLogger].
[2024-07-16 10:16:11] root INFO  - This is some root message
sylphrena0 commented 4 months ago

If you've tried that, the only other thing that I can think of is that the class might not be registering properly with log4cxx - this depends slightly on how log4cxx is built/the compiler.

You can try registering the class manually, call the NullWriterAppender::registerClass() method directly and then try loading your config file.

If that doesn't work, a minimal complete example would be helpful in order to debug what is going on.

Thanks, this solved my issue. This must be an issue with my cmake configuration or something of the sort.