Commit d3d0ad64 authored by Adrien Oliva's avatar Adrien Oliva

Merge branch '9-avoid-static' into 'master' (!)

Compatibility break!

Resolve "Avoid static"

Closes #9

See merge request !9
parents 70a6ae61 d8fdac9e
Pipeline #261 passed with stages
in 1 minute and 21 seconds
23 Adrien Oliva <olivaa+gitlab@yapbreak.fr>
24 Adrien Oliva <olivaa+gitlab@yapbreak.fr>
#include "yaplog.h"
__attribute__((destructor)) static void yaplog_static_deinit()
{
logger::unsetDestinationVariable();
logger::unsetLevelVariable();
logger::unsetColorVariable();
logger::unsetInfoVariable();
}
void logger::setDestinationVariable(const char *dest)
{
InternalLog::setDestinationVariable(dest);
}
void logger::setLevelVariable(const char *level)
{
InternalLog::setLevelVariable(level);
}
void logger::setColorVariable(const char *color)
{
InternalLog::setColorVariable(color);
}
void logger::setInfoVariable(const char *info)
{
InternalLog::setInfoVariable(info);
}
void logger::unsetDestinationVariable()
{
InternalLog::unsetDestinationVariable();
}
void logger::unsetLevelVariable()
{
InternalLog::unsetLevelVariable();
}
void logger::unsetColorVariable()
{
InternalLog::unsetColorVariable();
}
void logger::unsetInfoVariable()
{
InternalLog::unsetInfoVariable();
}
#ifndef YAPLOG_H_UGV90DZC
#define YAPLOG_H_UGV90DZC
#ifndef LOG_DEST
# define LOG_DEST "LOGDESTINATION"
#endif
#ifndef LOG_LEVEL
# define LOG_LEVEL "LOGLEVEL"
#endif
#ifndef LOG_COLOR
# define LOG_COLOR "LOGCOLOR"
#endif
#ifndef LOG_INFO
# define LOG_INFO "LOGINFO"
#endif
#include <yaplog/internallog.h>
#include <yaplog/dump.h>
#define yaplog_getlocation logger::log_location(__func__, \
__FILE__, \
__LINE__)
#define yaplog_getconf logger::conf(LOG_DEST, \
LOG_LEVEL, \
LOG_COLOR, \
LOG_INFO)
#define getLogger(level) logger::InternalLog(logger::log_level::level, \
yaplog_getlocation, \
yaplog_getconf \
)
/**
* @brief Fatal log macro utility to print a fatal message on stderr.
*/
#define FLOG() logger::InternalLog(logger::log_level::fatal, \
logger::log_location(__func__, \
__FILE__, \
__LINE__), \
logger::InternalLog::getOstream(), \
logger::InternalLog::getSystemLevel())
#define FLOG() getLogger(fatal)
/**
* @brief Alert log macro utility to print an alert message on stderr.
*/
#define ALOG() logger::InternalLog(logger::log_level::alert, \
logger::log_location(__func__, \
__FILE__, \
__LINE__), \
logger::InternalLog::getOstream(), \
logger::InternalLog::getSystemLevel())
#define ALOG() getLogger(alert)
/**
* @brief Critical log macro utility to print a critical message on stderr.
*/
#define CLOG() logger::InternalLog(logger::log_level::crit, \
logger::log_location(__func__, \
__FILE__, \
__LINE__), \
logger::InternalLog::getOstream(), \
logger::InternalLog::getSystemLevel())
#define CLOG() getLogger(crit)
/**
* @brief Error log macro utility to print an error message on stderr.
*/
#define ELOG() logger::InternalLog(logger::log_level::error, \
logger::log_location(__func__, \
__FILE__, \
__LINE__), \
logger::InternalLog::getOstream(), \
logger::InternalLog::getSystemLevel())
#define ELOG() getLogger(error)
/**
* @brief Warning log macro utility to print a warning message on stderr.
*/
#define WLOG() logger::InternalLog(logger::log_level::warn, \
logger::log_location(__func__, \
__FILE__, \
__LINE__), \
logger::InternalLog::getOstream(), \
logger::InternalLog::getSystemLevel())
#define WLOG() getLogger(warn)
/**
* @brief Notice log macro utility to print a notice message on stderr.
*/
#define NLOG() logger::InternalLog(logger::log_level::notice, \
logger::log_location(__func__, \
__FILE__, \
__LINE__), \
logger::InternalLog::getOstream(), \
logger::InternalLog::getSystemLevel())
#define NLOG() getLogger(notice)
/**
* @brief Information log macro utility to print an information message on
* stderr.
*/
#define ILOG() logger::InternalLog(logger::log_level::info, \
logger::log_location(__func__, \
__FILE__, \
__LINE__), \
logger::InternalLog::getOstream(), \
logger::InternalLog::getSystemLevel())
#define ILOG() getLogger(info)
/**
* @brief Debug log macro utility to print a debug message on stderr.
*/
#define DLOG() logger::InternalLog(logger::log_level::debug, \
logger::log_location(__func__, \
__FILE__, \
__LINE__), \
logger::InternalLog::getOstream(), \
logger::InternalLog::getSystemLevel())
#define DLOG() getLogger(debug)
/**
* @brief Trace log macro utility to print a trace message on stderr.
*/
#define TLOG() logger::InternalLog(logger::log_level::trace, \
logger::log_location(__func__, \
__FILE__, \
__LINE__), \
logger::InternalLog::getOstream(), \
logger::InternalLog::getSystemLevel())
namespace logger {
/**
* @brief Set environment variable to check for log file destination.
*
* @param dest New destination environement variable
*/
void setDestinationVariable(const char *dest);
void setLevelVariable(const char *level);
void setColorVariable(const char *color);
void setInfoVariable(const char *info);
void unsetDestinationVariable();
void unsetLevelVariable();
void unsetColorVariable();
void unsetInfoVariable();
};
#define TLOG() getLogger(trace)
#endif /* end of include guard: YAPLOG_H_UGV90DZC */
......@@ -5,6 +5,8 @@ include $(top_srcdir)/Makefile.common
noinst_LTLIBRARIES = libinternalyaplog.la
libinternalyaplog_la_SOURCES = dump.h
libinternalyaplog_la_SOURCES += dump.cpp
libinternalyaplog_la_SOURCES += conf.h
libinternalyaplog_la_SOURCES += conf.cpp
libinternalyaplog_la_SOURCES += internallog.h
libinternalyaplog_la_SOURCES += internallog.cpp
libinternalyaplog_la_SOURCES += level.h
......
#include "conf.h"
#include <iostream>
#include <fstream>
#include <cstring>
using namespace logger;
conf::conf(const char *destination,
const char *level,
const char *color,
const char *info)
: m_output(NULL)
, m_err(std::cerr.rdbuf())
, m_out(std::cout.rdbuf())
{
parse_destination(destination);
parse_level(level);
parse_color(color);
parse_info(info);
}
conf::~conf()
{
}
const log_level &conf::getSystemLevel() const
{
return m_systemlevel;
}
std::ostream *conf::getOutput() const
{
return m_output;
}
bool conf::getColor() const
{
return m_color;
}
bool conf::getInfo() const
{
return m_info;
}
void conf::parse_destination(const char *destination)
{
const char *value = getenv(destination);
if (value == NULL) {
m_output = &m_err;
} else {
if (strcmp(value, "stderr") == 0) {
m_output = &m_err;
} else if (strcmp(value, "stdout") == 0) {
m_output = &m_out;
} else {
m_file = std::ofstream(value, std::ofstream::app);
if (m_file.is_open()) {
m_output = &m_file;
} else {
std::cerr << "Fail to open " << value << std::endl;
m_output = &m_err;
}
}
}
}
void conf::parse_level(const char *level)
{
const char *loglevel = std::getenv(level);
if (loglevel == NULL) {
m_systemlevel = log_level::none;
} else {
try {
int value = std::stoi(loglevel);
if (value < 0)
m_systemlevel = log_level::none;
else if (value > 9)
m_systemlevel = log_level::trace;
else
m_systemlevel = static_cast<log_level>(value);
} catch (std::exception &) {
m_systemlevel = log_level::none;
}
}
}
void conf::parse_color(const char *color)
{
const char *value = std::getenv(color);
if (value == NULL) {
m_color = false;
} else {
try {
int val = std::stoi(value);
m_color = (val == 1);
} catch (std::exception &) {
m_color = false;
}
}
}
void conf::parse_info(const char *info)
{
const char *value = std::getenv(info);
if (value == NULL) {
m_info = false;
} else {
m_info = (strcmp(value, "debug") == 0);
}
}
#ifndef CONF_H_ESGKSFA9
#define CONF_H_ESGKSFA9
#include <ostream>
#include <fstream>
#include <yaplog/level.h>
namespace logger {
class InternalLog;
/**
* @brief Hold configuration of logger.
*/
class conf {
public:
/**
* @brief Constructor of conf logger object.
*
* @param destination Environment variable name where log
* destination will be set.
* @param level Environment variable name where log level will be
* set.
* @param color Environment variable name where log color will be
* set.
* @param info Environment variable name where log info will be set.
*/
conf(const char *destination,
const char *level,
const char *color,
const char *info);
~conf();
/**
* @brief Main logger class defined in internallog.h
*/
friend class InternalLog;
template<typename T>
friend const InternalLog &operator<<(const InternalLog &, const T &);
template<typename T>
friend const InternalLog &operator<<(const InternalLog &, const T *);
friend const InternalLog &operator<<(const InternalLog &out,
std::ostream &(*f)(std::ostream &));
protected:
/**
* @brief Get log level required by system configuration, as read
* in environment variable.
*
* @return System log level.
*/
const log_level &getSystemLevel() const;
/**
* @brief Get output stream where log needs to be written.
*
* @return Output stream pointer.
*/
std::ostream *getOutput() const;
/**
* @brief Color flag
*
* @return True if color is enabled.
*/
bool getColor() const;
/**
* @brief Info flag
*
* @return True if file, line and function information are enabled.
*/
bool getInfo() const;
private:
/**
* @brief Read `destination` environment variable and store
* corresponding output stream in object instance.
*
* @param destination Environment variable name to read.
*/
void parse_destination(const char *destination);
/**
* @brief Read `level` environment variable and store corresponding
* system log level in object instance.
*
* @param level Environment variable name to read.
*/
void parse_level(const char *level);
/**
* @brief Read `color` environment variable and store corresponding
* color flag in object instance.
*
* @param color Environment variable name to read.
*/
void parse_color(const char *color);
/**
* @brief Read `info` environment variable and store corresponding
* info flag in object instance.
*
* @param info Environment variable name to read.
*/
void parse_info(const char *info);
private:
/**
* @brief System log level.
*/
log_level m_systemlevel;
/**
* @brief Pointer to output stream to use.
*/
std::ostream *m_output;
/**
* @brief Repplication of stderr output stream.
*/
std::ostream m_err;
/**
* @brief Repplication of stdout output stream.
*/
std::ostream m_out;
/**
* @brief File output stream, valid if a file is given as
* destination.
*/
std::ofstream m_file;
/**
* @brief Color flag.
*/
bool m_color;
/**
* @brief Info flag.
*/
bool m_info;
};
};
#endif /* end of include guard: CONF_H_ESGKSFA9 */
......@@ -8,29 +8,22 @@
using namespace logger;
char *InternalLog::s_destination = NULL;
char *InternalLog::s_level = NULL;
char *InternalLog::s_color = NULL;
char *InternalLog::s_info = NULL;
InternalLog::InternalLog(log_level level, const log_location &loc,
std::ostream *destination,
log_level system_level)
InternalLog::InternalLog(log_level level,
const log_location &loc,
const conf &c)
: m_level(level)
, m_location(loc)
, m_output(destination)
, m_systemlevel(system_level)
, m_conf(c)
{
if (m_level <= m_systemlevel)
if (m_level <= m_conf.getSystemLevel())
print_header();
}
InternalLog::~InternalLog()
{
if (m_level <= m_systemlevel) {
if (m_level <= m_conf.getSystemLevel()) {
(*this) << "\n";
}
closeOstream(m_output);
}
char InternalLog::char_from_level(enum log_level l)
......@@ -61,167 +54,18 @@ char InternalLog::char_from_level(enum log_level l)
void InternalLog::print_header()
{
bool color = getColor();
(*m_output) << color_start(color)
<< "[" << char_from_level(m_level) << "]";
if (getInfo()) {
(*m_output) << " " << m_location.m_file << ":"
bool color = m_conf.getColor();
std::ostream *output = m_conf.getOutput();
(*output) << color_start(color)
<< "[" << char_from_level(m_level) << "]";
if (m_conf.getInfo()) {
(*output) << " " << m_location.m_file << ":"
<< m_location.m_line << "("
<< m_location.m_function << ")";
}
(*m_output) << color_end(color) << " ";
}
std::ostream *InternalLog::getOstream(const char *destination)
{
if (destination == NULL) {
return new std::ostream(std::cerr.rdbuf());
} else {
if (strcmp(destination, "stderr") == 0) {
return new std::ostream(std::cerr.rdbuf());
} else if (strcmp(destination, "stdout") == 0) {
return new std::ostream(std::cout.rdbuf());
} else {
std::ofstream *ofs;
ofs = new std::ofstream(destination, std::ofstream::app);
if (ofs != NULL && ofs->is_open()) {
return ofs;
} else {
std::cerr << "Fail to open " << destination << std::endl;
delete ofs;
return new std::ostream(std::cerr.rdbuf());
}
}
}
return new std::ostream(std::cerr.rdbuf());
}
std::ostream *InternalLog::getOstream()
{
const char *logdestination = std::getenv(getDestinationVariable());
return getOstream(logdestination);
}
void InternalLog::closeOstream(std::ostream *os)
{
delete os;
}
log_level InternalLog::getSystemLevel()
{
const char *cser_loglevel = std::getenv(getLevelVariable());
if (cser_loglevel == NULL) {
return log_level::none;
} else {
try {
int value = std::stoi(cser_loglevel);
if (value < 0)
return log_level::none;
if (value > 9)
return log_level::trace;
return static_cast<log_level>(value);
} catch (std::exception &) {
return log_level::none;
}
}
}
const char *InternalLog::getDestinationVariable()
{
return s_destination ? s_destination : YAPLOG_DEST_DEFAULT;
}
const char *InternalLog::getLevelVariable()
{
return s_level ? s_level : YAPLOG_LEVEL_DEFAULT;
}
const char *InternalLog::getColorVariable()
{
return s_color ? s_color : YAPLOG_COLOR_DEFAULT;
}
const char *InternalLog::getInfoVariable()
{
return s_info ? s_info : YAPLOG_INFO_DEFAULT;
}
void InternalLog::setDestinationVariable(const char *dest)
{
unsetDestinationVariable();
s_destination = strdup(dest);
}
void InternalLog::setLevelVariable(const char *level)
{
unsetLevelVariable();
s_level = strdup(level);
}
void InternalLog::setColorVariable(const char *color)
{
unsetColorVariable();
s_color = strdup(color);
}
void InternalLog::setInfoVariable(const char *info)
{
unsetInfoVariable();
s_info = strdup(info);
}
void InternalLog::unsetDestinationVariable()
{
if (s_destination != NULL)
free(static_cast<void *>(s_destination));
s_destination = NULL;
}
void InternalLog::unsetLevelVariable()
{
if (s_level != NULL)
free(static_cast<void *>(s_level));
s_level = NULL;
}
void InternalLog::unsetColorVariable()
{
if (s_color != NULL)
free(static_cast<void *>(s_color));
s_color = NULL;
}
void InternalLog::unsetInfoVariable()
{
if (s_info != NULL)
free(static_cast<void *>(s_info));
s_info = NULL;
}
bool InternalLog::getColor()
{
const char *color = std::getenv(getColorVariable());
if (color == NULL) {
return false;
} else {
try {
int value = std::stoi(color);
return (value == 1);
} catch (std::exception &) {
return false;
}
}
(*output) << color_end(color) << " ";
}
bool InternalLog::getInfo()
{
const char *info = std::getenv(getInfoVariable());
if (info == NULL) {
return false;
} else {
return (strcmp(info, "debug") == 0);
}
}
const char *InternalLog::color_start(bool color)
......
......@@ -3,6 +3,7 @@
#include <yaplog/level.h>
#include <yaplog/loglocation.h>
#include <yaplog/conf.h>
#include <ostream>
......@@ -25,12 +26,11 @@ namespace logger {
*
* @param level The log level of the given logger.
* @param loc Information of location of log in code base.
* @param destination Standard output stream to be used.
* @param system_level System log level.
* @param c Logger configuration
*/
InternalLog(log_level level, const log_location &loc,
std::ostream *destination,
log_level system_level = log_level::trace);
InternalLog(log_level level,
const log_location &loc,
const conf &c);
virtual ~InternalLog();
......@@ -40,15 +40,6 @@ namespace logger {
template<typename T>