From 99bdd49f2f90802c43a810d00470bb1f45f43456 Mon Sep 17 00:00:00 2001 From: Danny Robson Date: Tue, 24 Apr 2012 17:38:35 +1000 Subject: [PATCH] Add first pass at logging code --- Makefile.am | 3 ++ log.cpp | 89 +++++++++++++++++++++++++++++++++++++++++++++++++++++ log.hpp | 65 ++++++++++++++++++++++++++++++++++++++ log.ipp | 43 ++++++++++++++++++++++++++ 4 files changed, 200 insertions(+) create mode 100644 log.cpp create mode 100644 log.hpp create mode 100644 log.ipp diff --git a/Makefile.am b/Makefile.am index 07cb3677..c2087f7c 100644 --- a/Makefile.am +++ b/Makefile.am @@ -46,6 +46,9 @@ UTIL_FILES = \ json.hpp \ lerp.cpp \ lerp.hpp \ + log.cpp \ + log.hpp \ + log.ipp \ maths.cpp \ maths.hpp \ maths/matrix.cpp \ diff --git a/log.cpp b/log.cpp new file mode 100644 index 00000000..73fc8f99 --- /dev/null +++ b/log.cpp @@ -0,0 +1,89 @@ +/* + * This file is part of libgim. + * + * libgim is free software: you can redistribute it and/or modify it under the + * terms of the GNU General Public License as published by the Free Software + * Foundation, either version 3 of the License, or (at your option) any later + * version. + * + * libgim is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more + * details. + * + * You should have received a copy of the GNU General Public License + * along with libgim. If not, see . + * + * Copyright 2012 Danny Robson + */ + + +#include "log.hpp" + +#include "debug.hpp" +#include "types.hpp" + +#include +#include + +#include + +using namespace util; +using std::string; + +void +check_level (level_t l) + { check (l >= 0 && l < NUM_LEVELS); } + + +const string& +level_to_string (level_t l) { + check_level (l); + + static const std::string level_names[] = { + "EMERGENCY", + "ALERT", + "CRITICAL", + "ERROR", + "WARNING", + "NOTICE", + "INFORMATIONAL", + "DEBUG" + }; + + return level_names[l]; +} + + +std::ostream& +util::operator<< (std::ostream& os, level_t l) { + os << level_to_string (l); + return os; +} + + +void +util::log (level_t l, const std::string &format) + { detail::log (l, boost::format (format)); } + + +void +util::detail::log (level_t level, boost::format &&format) { + static const boost::format LEVEL_FORMAT ("%s [%s] "); + + char time_string[strlen("YYYY-mm-dd HHMMh") + 1]; + time_t unix_time = time (nullptr); + if (0 == strftime (time_string, + elems (time_string), + "%Y-%m-%d %H%Mh", + localtime (&unix_time))) { + unusual (); + return; + } + + std::cerr << boost::format (LEVEL_FORMAT) + % time_string + % level + << format + << "\n"; +} diff --git a/log.hpp b/log.hpp new file mode 100644 index 00000000..4abc0920 --- /dev/null +++ b/log.hpp @@ -0,0 +1,65 @@ +/* + * This file is part of libgim. + * + * libgim is free software: you can redistribute it and/or modify it under the + * terms of the GNU General Public License as published by the Free Software + * Foundation, either version 3 of the License, or (at your option) any later + * version. + * + * libgim is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more + * details. + * + * You should have received a copy of the GNU General Public License + * along with libgim. If not, see . + * + * Copyright 2012 Danny Robson + */ + +#ifndef __UTIL_LOG_HPP +#define __UTIL_LOG_HPP + +#include +#include + +namespace util { + // rfc5424 log levels. It is assumed they are contiguous to simplify array + // indexing in logging code. + // + enum level_t { + EMERGENCY, /** system is unusable */ + ALERT, /** action must be taken immediately */ + CRITICAL, /** critical conditions */ + ERROR, /** error conditions */ + WARNING, /** warning conditions */ + NOTICE, /** normal but significant condition */ + INFORMATIONAL, + INFO = INFORMATIONAL, /** informational messages */ + DEBUG, /** debug-level messages */ + + NUM_LEVELS + }; + + std::ostream& + operator<< (std::ostream&, level_t); + + void log (level_t, const std::string &format); + + template + void log (level_t, const std::string &format, tail ..._tail); + + #define LOG_EMERGENCY(...) do { log(util::EMERGENCY, ##__VA_ARGS__); } while (0) + #define LOG_ALERT(...) do { log(util::ALERT, ##__VA_ARGS__); } while (0) + #define LOG_CRITICAL(...) do { log(util::CRITICAL, ##__VA_ARGS__); } while (0) + #define LOG_ERROR(...) do { log(util::ERROR, ##__VA_ARGS__); } while (0) + #define LOG_WARNING(...) do { log(util::WARNING, ##__VA_ARGS__); } while (0) + #define LOG_NOTICE(...) do { log(util::NOTICE, ##__VA_ARGS__); } while (0) + #define LOG_INFO(...) do { log(util::INFO, ##__VA_ARGS__); } while (0) + #define LOG_DEBUG(...) do { log(util::DEBUG, ##__VA_ARGS__); } while (0) +} + +#include "log.ipp" + +#endif + diff --git a/log.ipp b/log.ipp new file mode 100644 index 00000000..9c70b49e --- /dev/null +++ b/log.ipp @@ -0,0 +1,43 @@ +/* + * This file is part of libgim. + * + * libgim is free software: you can redistribute it and/or modify it under the + * terms of the GNU General Public License as published by the Free Software + * Foundation, either version 3 of the License, or (at your option) any later + * version. + * + * libgim is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more + * details. + * + * You should have received a copy of the GNU General Public License + * along with libgim. If not, see . + * + * Copyright 2012 Danny Robson + */ + +#ifndef __UTIL_LOG_IPP +#define __UTIL_LOG_IPP + +#include + +namespace util { + namespace detail { + void + log (level_t l, boost::format &&format); + + template + void + log (level_t l, boost::format &&format, const T &val, tail ..._tail) { + ::util::detail::log (l, std::move (format % val), _tail...); + } + } + + template + void log (level_t l, const std::string &format, tail ..._tail) + { detail::log (l, std::move (boost::format (format)), _tail...); } +} + + +#endif