如何从log4cxx的RollingFileAppender获取日志目录?
可靠获取log4cxx RollingFileAppender日志目录的方法
方法1:自定义Tracked Appender(推荐)
自己实现一个继承自RollingFileAppender的子类,在初始化阶段捕获并存储实际创建的日志目录,避免类型转换的不确定性:
class TrackedRollingFileAppender : public log4cxx::RollingFileAppender { public: DECLARE_LOG4CXX_OBJECT(TrackedRollingFileAppender) BEGIN_LOG4CXX_CAST_MAP() LOG4CXX_CAST_ENTRY(TrackedRollingFileAppender) LOG4CXX_CAST_ENTRY_CHAIN(RollingFileAppender) END_LOG4CXX_CAST_MAP() void activateOptions(log4cxx::helpers::Pool& pool) override { RollingFileAppender::activateOptions(pool); // 从完整文件路径中提取目录部分 std::string fullFilePath = getFile(); size_t lastSeparator = fullFilePath.find_last_of("/\\"); if (lastSeparator != std::string::npos) { m_logDirectory = fullFilePath.substr(0, lastSeparator); } } const std::string& getLogDirectory() const { return m_logDirectory; } private: std::string m_logDirectory; }; // 注册自定义Appender LOG4CXX_IMPLEMENT_OBJECT(TrackedRollingFileAppender)
- 在XML配置中,将原
RollingFileAppender替换为这个自定义类的全限定名 - 获取路径时,直接通过
Logger::getAppender()拿到实例后用static_cast转换(因为你明确知道配置的是自定义类),调用getLogDirectory()即可
方法2:用log4cxx内置宏做安全类型转换
利用log4cxx提供的LOG4CXX_INSTANCEOF宏做类型校验,替代不可靠的dynamic_cast:
log4cxx::AppenderPtr appender = log4cxx::Logger::getRootLogger()->getAppender("YourAppenderName"); if (LOG4CXX_INSTANCEOF(RollingFileAppender, appender)) { auto rollingAppender = static_cast<log4cxx::RollingFileAppender*>(appender.get()); std::string fullFilePath = rollingAppender->getFile(); // 提取目录逻辑同方法1 size_t lastSeparator = fullFilePath.find_last_of("/\\"); std::string logDir = fullFilePath.substr(0, lastSeparator); // 使用logDir }
这个宏是log4cxx专门用于判断Appender类型的,比原生RTTI转换更可靠。
方法3:预生成目录路径并全局存储
在log4cxx初始化前,先生成时间戳对应的目录路径,存入全局变量或系统属性,再在XML配置中引用:
// 程序启动时生成日志目录 std::time_t now = std::time(nullptr); char timeBuf[32]; std::strftime(timeBuf, sizeof(timeBuf), "%Y/%m/%d/%H%M", std::localtime(&now)); std::string globalLogDir = "/base/log/path/" + std::string(timeBuf); // 存入系统属性供XML引用 log4cxx::helpers::System::setProperty("appLogDir", globalLogDir);
XML配置示例:
<appender name="RollingFile" class="org.apache.log4j.RollingFileAppender"> <param name="File" value="${appLogDir}/app.log"/> <!-- 其他滚动配置 --> </appender>
程序结束时直接读取全局变量globalLogDir即可,完全不需要从Appender中提取路径。
内容的提问来源于stack exchange,提问作者Alex
相关产品推荐
相关产品推荐

