You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@logging.apache.org by "Robert Middleton (Jira)" <lo...@logging.apache.org> on 2022/05/11 01:25:00 UTC

[jira] [Commented] (LOGCXX-553) log4cxx::spi::LocationInfo constructor backward compatibility

    [ https://issues.apache.org/jira/browse/LOGCXX-553?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=17534634#comment-17534634 ] 

Robert Middleton commented on LOGCXX-553:
-----------------------------------------

That is intended as an internal class for the most part; however it should not be hard to make it backwards-compatible(I actually ran into a similar issue with this earlier).

Some suggestions for you:
 * As of 0.13.0, there are new macros defined in log4cxx.h to define the versions of log4cxx.  You can use those to determine the version currently in use.
 * The simplest way to fix this problem on your side is to change 
::log4cxx::spi::LocationInfo( file.c_str(), fn.c_str(), line );to the macro [LOG4CXX_LOCATION|https://github.com/apache/logging-log4cxx/blob/6cc5d910b788c8cf116e4dd348db93746086ad0d/src/main/include/log4cxx/spi/location/locationinfo.h#L173] which handles the creation of the location for you.  The definition of the macro hasn't changed so it is source-compatible with 0.13.0 and previous versions.

> log4cxx::spi::LocationInfo constructor backward compatibility
> -------------------------------------------------------------
>
>                 Key: LOGCXX-553
>                 URL: https://issues.apache.org/jira/browse/LOGCXX-553
>             Project: Log4cxx
>          Issue Type: Bug
>          Components: Core
>    Affects Versions: 0.13.0
>            Reporter: Nir Arad
>            Priority: Major
>
> h1. Issue
> The LocationInfo constructor was changed from 0.12.1 to 0.13.0 in a non-backward compatible way.
> In 0.12.1:
> {code:c++}
> LocationInfo( const char* const fileName, const char* const functionName, int lineNumber);{code}
> In 0.13.0:
> {code:c++}
> LocationInfo (const char *const fileName, const char *const shortFileName, const char *const functionName, int lineNumber);
> {code}
> Specifically, a new argument (shortFileName) was added to the constructor argument list.
> [https://logging.apache.org/log4cxx/latest_stable/classlog4cxx_1_1spi_1_1LocationInfo.html]
> h1. Requested change
> Add back the old constructor, so both constructors would work.
> h1. Motivation
> Using version 0.11.0, I wrote a tracer class that reports +entry and exit+ from functions in my code, when TRACE log level is enabled. The way it works is roughly this:
> Traced function code:
>  
> {code:c++}
> // a LoggerPtr named logger was previously created and is available in this scope
> void my_func() {
>     MY_TRACER( logger );
>     // some code
> }
> {code}
> Note that I don't need to place any code at the exit from the function.
> The definition of MY_TRACER macro is:
> {code:c++}
> #define MY_TRACER( logger )         \
>   LogTracer __log_tracer( logger, __PRETTY_FUNCTION__, __FILE__, __LINE__ ){code}
> The idea is that an object of type LogTracer (named __log_tracer) is created at the beginning of the function. Its constructor reports entry to the function, and as it goes out of scope it reports the exit from the function.
> The LogTracer class looks like this:
> {code:c++}
> class LogTracer {
> public:
>   LogTracer( LoggerPtr logger, std::string fn, std::string file, int line ) {
>     std::stringstream message;
>     this->logger = logger;
>     this->fn     = fn;
>     this->file   = file;
>     this->line   = line;
>     auto location_info =
>         ::log4cxx::spi::LocationInfo( file.c_str(), fn.c_str(), line );
>     message << "Entering " << fn;
>     if ( LOG4CXX_UNLIKELY( logger->isTraceEnabled() ) ) {
>       ::log4cxx::helpers::MessageBuffer oss_;
>       logger->forcedLog(
>           ::log4cxx::Level::getTrace(),
>           oss_.str( oss_ << message.str() ),
>           location_info );
>     }
>   }
>   ~LogTracer() {
>     std::stringstream message;
>     message << "Leaving " << fn;
>     auto location_info =
>         ::log4cxx::spi::LocationInfo( file.c_str(), fn.c_str(), line );
>     if ( LOG4CXX_UNLIKELY( logger->isTraceEnabled() ) ) {
>       ::log4cxx::helpers::MessageBuffer oss_;
>       logger->forcedLog(
>           ::log4cxx::Level::getTrace(),
>           oss_.str( oss_ << message.str() ),
>           location_info );
>     }
>   }
> private:
>   LoggerPtr   logger;
>   std::string fn;
>   std::string file;
>   int         line;
> };
> {code}
>  
> As you can see, I use the line number of the MY_TRACE() statement in both the entry and the exit, since I have no way to know in what line of code did the function end, and that's ok. In fact it's better, since if there is a problem with the function, I'd rather jump to its beginning to inspect the code.
> The point is that to create a meaningful entry with forcedLog(), I need to create a LocationInfo object.
> The change in constructor broke my code when I tried to deploy it to a new environment with log4cxx version 0.13.0.
> h1. Additional thoughts / suggestions
> I don't know if log4cxx provides macros with the version numbers. I couldn't find any. That would have allowed me to make my code compatible between versions.
> I believe I read that the log4cxx::spi interface is supposed to an internal, private interface. I would suggest to make LocationInfo a public interface for uses like I described here. I realize it is not a common or intended use, but it does seem to be something that other people may want to do.
> I am aware of the horrendous performance implications of instrumenting all the functions in my code like this. I prevent that with guard code controlled by a preprocessor flag that enables this macro or maps it to nothing.
> Suggestions for a better implementation are welcome.
>  



--
This message was sent by Atlassian Jira
(v8.20.7#820007)