DebugLogs are now being redirected to the correct files

This commit is contained in:
Felipe Zimmerle
2015-08-27 01:27:34 -03:00
parent 01542e28c3
commit 24b7d72666
14 changed files with 330 additions and 177 deletions

View File

@@ -169,6 +169,8 @@ libmodsecurity_la_SOURCES = \
rules.cc \
utils.cc \
debug_log.cc \
debug_log_writer.cc \
debug_log_writer_agent.cc \
macro_expansion.cc \
request_body_processor/multipart.cc \
request_body_processor/multipart_blob.cc \

View File

@@ -19,122 +19,60 @@
#include <fstream>
#include "src/debug_log_writer.h"
#include "src/debug_log_writer_agent.h"
namespace ModSecurity {
/**
* @name new_instance
* @brief Create a new instance of the DebugLog.
*
* @return Debug log pointer
* @retval >0 Debug log structure was initialized correctly
* @retval NULL Debug log could not be initialized.
*
*/
DebugLog *DebugLog::new_instance() {
return new DebugLog();
DebugLog::~DebugLog() {
DebugLogWriter::getInstance().close(m_fileName);
}
/**
* @name setOutputFile
* @brief Set an output file where the log will be saved
*
* @param file_path Path to the log file.
*
* @return If the operation successful or not.
* @retval true Operation was successful.
* @retval false Operation failed.
*
*/
bool DebugLog::setOutputFile(const std::string& file_path) {
if (is_open()) {
close();
void DebugLog::setDebugLogFile(const std::string& fileName) {
m_fileName = fileName;
if (isLogFileSet()) {
DebugLogWriter::getInstance().close(m_fileName);
}
open(file_path, std::fstream::out | std::fstream::app);
if (!is_open()) {
return false;
}
return true;
DebugLogWriter::getInstance().open(m_fileName);
}
/**
* @name write_log
* @brief Write a message into the debug log.
*
* @param debug_level Debug level of the given message.
* @param text Message to be written.
*
* @return If the operation successful or not.
* @retval true Operation was successful.
* @retval false Operation failed.
*
*/
bool DebugLog::write_log(int debug_level, const std::string &text) {
std::cout << "?" << std::to_string(is_open()) << ":" << std::to_string(m_debug_level) <<" [" << debug_level << "] " << text << std::endl;
if (!is_open()) {
return false;
}
if (debug_level <= m_debug_level) {
*this << "[" << debug_level << "] " << text << std::endl;
}
return true;
void DebugLog::setDebugLogLevel(int level) {
m_debugLevel = level;
}
/**
* @name setDebugLevel
* @brief Changes the default debug level.
*
* @param level Debug level.
*
* @return If the operation successful or not.
* @retval true Operation was successful.
* @retval false Operation failed.
*
*/
bool DebugLog::setDebugLevel(int level) {
if (level < 0 || level > 9) {
return false;
bool DebugLog::isLogFileSet() {
return m_fileName.empty() == false;
}
bool DebugLog::isLogLevelSet() {
return m_debugLevel != -1;
}
const std::string& DebugLog::getDebugLogFile() {
return m_fileName;
}
int DebugLog::getDebugLogLevel() {
if (m_debugLevel < 0) {
return 0;
}
m_debug_level = level;
return true;
return m_debugLevel;
}
/**
* @name isConfigured
* @brief Returns if debug log is configured or not.
*
* @return If the debug log is configured or not
* @retval true It is configured.
* @retval false It is not configured.
*
*/
bool DebugLog::isConfigured() {
return m_is_configured;
}
void DebugLog::refCountDecreaseAndCheck(void) {
this->m_referenceCount--;
if (this->m_referenceCount == 0) {
delete this;
void DebugLog::write(int level, const std::string &msg) {
if (level <= m_debugLevel) {
DebugLogWriter::getInstance().write(m_fileName, "[" + std::to_string(level) + "] " + msg);
}
}
void DebugLog::refCountIncrease(void) {
this->m_referenceCount++;
}
} // namespace ModSecurity
} // namespace ModSecurity

72
src/debug_log_writer.cc Normal file
View File

@@ -0,0 +1,72 @@
/*
* ModSecurity, http://www.modsecurity.org/
* Copyright (c) 2015 Trustwave Holdings, Inc. (http://www.trustwave.com/)
*
* You may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* If any of the files related to licensing are missing or if you have any
* other questions related to licensing please contact Trustwave Holdings, Inc.
* directly using the email address security@modsecurity.org.
*
*/
#include "src/debug_log_writer.h"
#include <stddef.h>
#include <fstream>
#include "src/debug_log_writer_agent.h"
namespace ModSecurity {
void DebugLogWriter::open(const std::string& fileName) {
std::map<std::string, DebugLogWriterAgent *>::iterator it;
DebugLogWriterAgent *agent;
it = agents.find(fileName);
if (it != agents.end()) {
agent = it->second;
} else {
agent = new DebugLogWriterAgent(fileName);
agents[fileName] = agent;
}
agent->refCountIncrease();
}
void DebugLogWriter::close(const std::string& fileName) {
#if 0
std::map<std::string, DebugLogWriterAgent *>::iterator it;
DebugLogWriterAgent *agent;
it = agents.find(fileName);
if (it != agents.end()) {
agent = it->second;
if (agent->refCountDecreaseAndCheck()) {
agents.erase(it);
}
}
#endif
}
void DebugLogWriter::write(const std::string& file, const std::string &msg) {
std::map<std::string, DebugLogWriterAgent *>::iterator it;
DebugLogWriterAgent *agent;
it = agents.find(file);
if (it != agents.end()) {
agent = it->second;
agent->write(msg);
} else {
std::cout << file << ": " << msg << std::endl;
}
}
} // namespace ModSecurity

57
src/debug_log_writer.h Normal file
View File

@@ -0,0 +1,57 @@
/*
* ModSecurity, http://www.modsecurity.org/
* Copyright (c) 2015 Trustwave Holdings, Inc. (http://www.trustwave.com/)
*
* You may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* If any of the files related to licensing are missing or if you have any
* other questions related to licensing please contact Trustwave Holdings, Inc.
* directly using the email address security@modsecurity.org.
*
*/
#include <iostream>
#include <map>
#include <string>
#ifndef SRC_DEBUG_LOG_WRITER_H_
#define SRC_DEBUG_LOG_WRITER_H_
#include "debug_log_writer_agent.h"
namespace ModSecurity {
/** @ingroup ModSecurity_CPP_API */
class DebugLogWriter {
public:
static DebugLogWriter& getInstance() {
static DebugLogWriter instance;
return instance;
}
void write(const std::string& file, const std::string& msg);
void close(const std::string& m_fileName);
void open(const std::string& m_fileName);
private:
DebugLogWriter() {};
// C++ 03
// ========
// Dont forget to declare these two. You want to make sure they
// are unacceptable otherwise you may accidentally get copies of
// your singleton appearing.
DebugLogWriter(DebugLogWriter const&);
void operator=(DebugLogWriter const&);
std::map<std::string, DebugLogWriterAgent *> agents;
};
} // namespace ModSecurity
#endif // SRC_DEBUG_LOG_WRITER_H_

View File

@@ -0,0 +1,46 @@
/*
* ModSecurity, http://www.modsecurity.org/
* Copyright (c) 2015 Trustwave Holdings, Inc. (http://www.trustwave.com/)
*
* You may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* If any of the files related to licensing are missing or if you have any
* other questions related to licensing please contact Trustwave Holdings, Inc.
* directly using the email address security@modsecurity.org.
*
*/
#include "src/debug_log_writer_agent.h"
#include <stddef.h>
#include <fstream>
#include "debug_log_writer.h"
namespace ModSecurity {
DebugLogWriterAgent::DebugLogWriterAgent(const std::string& fileName) :
m_referenceCount(0),
m_fileName(fileName) {
open(m_fileName, std::fstream::out | std::fstream::app);
}
void DebugLogWriterAgent::write(const std::string& msg) {
if (!is_open()) {
std::cout << "Agent: " << m_fileName << ": " << msg << std::endl;
return;
}
*this << msg << std::endl;
*this << flush();
}
} // namespace ModSecurity

View File

@@ -0,0 +1,56 @@
/*
* ModSecurity, http://www.modsecurity.org/
* Copyright (c) 2015 Trustwave Holdings, Inc. (http://www.trustwave.com/)
*
* You may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* If any of the files related to licensing are missing or if you have any
* other questions related to licensing please contact Trustwave Holdings, Inc.
* directly using the email address security@modsecurity.org.
*
*/
#include <iostream>
#include <fstream>
#include <string>
#ifndef SRC_DEBUG_LOG_WRITER_AGENT_H_
#define SRC_DEBUG_LOG_WRITER_AGENT_H_
namespace ModSecurity {
/** @ingroup ModSecurity_CPP_API */
class DebugLogWriterAgent : public std::ofstream {
public:
DebugLogWriterAgent(const std::string& fileName);
~DebugLogWriterAgent() {
if (is_open()) {
close();
}
}
void write(const std::string& msg);
bool refCountDecreaseAndCheck() {
this->m_referenceCount--;
if (this->m_referenceCount == 0) {
delete this;
return true;
}
return false;
}
void refCountIncrease() {
this->m_referenceCount++;
}
int m_referenceCount;
std::string m_fileName;
};
} // namespace ModSecurity
#endif // SRC_DEBUG_LOG_WRITER_AGENT_H_

View File

@@ -373,11 +373,23 @@ expression:
/* Debug log: start */
| CONFIG_DIR_DEBUG_LVL
{
driver.debugLevel = atoi($1.c_str());
if (driver.m_debugLog != NULL) {
driver.m_debugLog->setDebugLogLevel(atoi($1.c_str()));
} else {
driver.parserError << "Internal error, there is no DebugLog ";
driver.parserError << "object associated with the driver class";
YYERROR;
}
}
| CONFIG_DIR_DEBUG_LOG
{
driver.debug_log_path = $1;
if (driver.m_debugLog != NULL) {
driver.m_debugLog->setDebugLogFile($1);
} else {
driver.parserError << "Internal error, there is no DebugLog ";
driver.parserError << "object associated with the driver class";
YYERROR;
}
}
/* Debug log: end */
| CONFIG_DIR_GEO_DB

View File

@@ -91,10 +91,6 @@ Rules::~Rules() {
if (audit_log) {
audit_log->refCountDecreaseAndCheck();
}
/** Cleanup debug log */
if (debugLog) {
debugLog->refCountDecreaseAndCheck();
}
}
@@ -197,27 +193,25 @@ int Rules::merge(Driver *from) {
this->secRuleEngine = from->secRuleEngine;
this->secRequestBodyAccess = from->secRequestBodyAccess;
this->secResponseBodyAccess = from->secResponseBodyAccess;
this->debug_log_path = from->debug_log_path;
this->debugLevel = from->debugLevel;
if (from->m_debugLog && this->m_debugLog &&
from->m_debugLog->isLogFileSet()) {
this->m_debugLog->setDebugLogFile(from->m_debugLog->getDebugLogFile());
}
if (from->m_debugLog && this->m_debugLog &&
from->m_debugLog->isLogLevelSet()) {
this->m_debugLog->setDebugLogLevel(
from->m_debugLog->getDebugLogLevel());
}
this->components = from->components;
this->requestBodyLimit = from->requestBodyLimit;
this->responseBodyLimit = from->responseBodyLimit;
this->requestBodyLimitAction = from->requestBodyLimitAction;
this->responseBodyLimitAction = from->responseBodyLimitAction;
if (customDebugLog) {
this->debugLog = customDebugLog->new_instance();
} else {
this->debugLog = new DebugLog();
}
this->debugLog->refCountIncrease();
this->audit_log = from->audit_log;
this->audit_log->refCountIncrease();
this->debugLog->setDebugLevel(from->debugLevel);
this->debugLog->setOutputFile(from->debug_log_path);
return amount_of_rules;
}
@@ -243,28 +237,28 @@ int Rules::merge(Rules *from) {
this->requestBodyLimitAction = from->requestBodyLimitAction;
this->responseBodyLimitAction = from->responseBodyLimitAction;
if (customDebugLog) {
this->debugLog = customDebugLog->new_instance();
} else {
this->debugLog = new DebugLog();
if (from->m_debugLog && this->m_debugLog &&
from->m_debugLog->isLogFileSet()) {
this->m_debugLog->setDebugLogFile(from->m_debugLog->getDebugLogFile());
}
if (from->m_debugLog && this->m_debugLog &&
from->m_debugLog->isLogLevelSet()) {
this->m_debugLog->setDebugLogLevel(
from->m_debugLog->getDebugLogLevel());
}
this->debugLog->refCountIncrease();
this->audit_log = from->audit_log;
if (this->audit_log != NULL) {
this->audit_log->refCountIncrease();
}
this->debugLog->setDebugLevel(from->debugLevel);
this->debugLog->setOutputFile(from->debug_log_path);
return amount_of_rules;
}
void Rules::debug(int level, std::string message) {
if (debugLog != NULL) {
debugLog->write_log(level, message);
if (m_debugLog != NULL) {
m_debugLog->write(level, message);
}
}