Added test for Logger and debugged it

This commit is contained in:
mpc
2004-07-03 21:53:10 +00:00
committed by zzz
parent 121c0d89f2
commit d8f0f1a1d3
3 changed files with 87 additions and 25 deletions

View File

@@ -28,12 +28,12 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
#include <cassert>
#include <cstdarg> #include <cstdarg>
#include <cstdio> #include <cstdio>
#include <iostream> #include <iostream>
#include <string> #include <string>
using namespace std; using namespace std;
#include "mutex.hpp"
#include "time.hpp" #include "time.hpp"
#include "logger.hpp" #include "logger.hpp"
using namespace Libsockthread; using namespace Libsockthread;
@@ -91,19 +91,27 @@ void Logger::log(priority_t priority, const char* format, ...)
string s; string s;
Time t; Time t;
logger_m.lock(); logger_m.lock();
assert(logf != 0);
fprintf(logf, "%c@%s: ", ll, t.utc(s).c_str()); if (logf != 0) {
vfprintf(logf, format, ap); /*
fputc('\n', logf); * Remember! If you change the format here, change it in the else too
*/
fprintf(logf, "%c %s ", ll, t.utc(s).c_str());
vfprintf(logf, format, ap);
fputc('\n', logf);
if (fflush(logf) == EOF) {
cerr_m.lock();
cerr << "fflush() failed: " << strerror(errno) << '\n';
cerr_m.unlock();
}
} else {
// if they don't have an open log file, just use stderr
fprintf(stderr, "%c %s ", ll, t.utc(s).c_str());
vfprintf(stderr, format, ap);
fputc('\n', stderr);
}
va_end(ap); va_end(ap);
if (fflush(logf) == EOF) {
cerr_m.lock();
cerr << "fflush() failed: " << strerror(errno) << '\n';
cerr_m.unlock();
}
logger_m.unlock(); logger_m.unlock();
return; return;
@@ -115,16 +123,40 @@ void Logger::log(priority_t priority, const char* format, ...)
* *
* file - file location to open * file - file location to open
*/ */
void Logger::open(const string& file) bool Logger::open(const string& file)
{ {
close(); close();
logger_m.lock(); logger_m.lock();
logf = fopen(file.c_str(), "a"); logf = fopen(file.c_str(), "a");
logger_m.unlock(); logger_m.unlock();
if (logf == NULL) { if (logf != NULL) {
return true;
} else {
cerr_m.lock(); cerr_m.lock();
cerr << "fopen() failed (" << file << "): " << strerror(errno) << '\n'; cerr << "fopen() failed (" << file << "): " << strerror(errno) << '\n';
cerr_m.unlock(); cerr_m.unlock();
throw Logger_error("Error opening log file"); return false;
} }
} }
#ifdef UNIT_TEST
// g++ -Wall -c thread.cpp -o thread.o
// g++ -Wall -c mutex.cpp -o mutex.o
// g++ -Wall -c time.cpp -o time.o
// g++ -Wall -DUNIT_TEST -c logger.cpp -o logger.o
// g++ -Wall -DUNIT_TEST logger.o mutex.o thread.o time.o -o logger -lpthread
int main(void)
{
Logger logger;
logger.open("delete.me");
logger.set_loglevel(Logger::MINOR);
logger.close();
LWARNS("This should appear on stderr");
logger.open("delete.me.also");
LINFO("%s\n", "hey it works");
LDEBUGS("This shouldn't be saved in the file.");
return 0;
}
#endif // UNIT_TEST

View File

@@ -31,6 +31,41 @@
#ifndef LIBSOCKTHREAD_LOGGER_HPP #ifndef LIBSOCKTHREAD_LOGGER_HPP
#define LIBSOCKTHREAD_LOGGER_HPP #define LIBSOCKTHREAD_LOGGER_HPP
/*
* Some helpful macros:
*
* LDEBUG - debugging messages
* LMINOR - unimportant messages
* LINFO - informational messages
* LWARN - errors we automatically recover from
* LERROR - major, important errors
*
* Obviously, these only work if your Logger object is called "logger" and is
* global
*/
// Prints out the file name, function name, and line number before the message
#define LDEBUG(format, ...) logger.log(Logger::DEBUG, "%s:%s:%d:" \
format, __FILE__, __func__, __LINE__, __VA_ARGS__)
// This is the same as above, except it doesn't accept varargs
#define LDEBUGS(str) logger.log(Logger::DEBUG, "%s:%s:%d:" \
str, __FILE__, __func__, __LINE__);
#define LMINOR(format, ...) logger.log(Logger::MINOR, "%s:%s:%d:" \
format, __FILE__, __func__, __LINE__, __VA_ARGS__)
#define LMINORS(str) logger.log(Logger::MINOR, "%s:%s:%d:" \
str, __FILE__, __func__, __LINE__);
#define LINFO(format, ...) logger.log(Logger::INFO, "%s:%s:%d:" \
format, __FILE__, __func__, __LINE__, __VA_ARGS__)
#define LINFOS(str) logger.log(Logger::INFO, "%s:%s:%d:" \
str, __FILE__, __func__, __LINE__);
#define LWARN(format, ...) logger.log(Logger::WARN, "%s:%s:%d:" \
format, __FILE__, __func__, __LINE__, __VA_ARGS__)
#define LWARNS(str) logger.log(Logger::WARN, "%s:%s:%d:" \
str, __FILE__, __func__, __LINE__);
#define LERROR(format, ...) logger.log(Logger::ERROR, "%s:%s:%d:" \
format, __FILE__, __func__, __LINE__, __VA_ARGS__)
#define LERRORS(str) logger.log(Logger::ERROR, "%s:%s:%d:" \
str, __FILE__, __func__, __LINE__);
namespace Libsockthread { namespace Libsockthread {
class Logger { class Logger {
public: public:
@@ -43,23 +78,18 @@ namespace Libsockthread {
void close(void); void close(void);
void log(priority_t priority, const char* format, ...); void log(priority_t priority, const char* format, ...);
priority_t get_loglevel(void) const priority_t get_loglevel(void)
{ mutex.lock(); priority_t ll = loglevel; mutex.unlock(); return ll; } { logger_m.lock(); priority_t ll = loglevel; logger_m.unlock();
void open(const string& file); // throws Logger_error return ll; }
bool open(const string& file);
void set_loglevel(priority_t priority) void set_loglevel(priority_t priority)
{ mutex.lock(); loglevel = priority; mutex.unlock(); } { logger_m.lock(); loglevel = priority; logger_m.unlock(); }
private: private:
Mutex cerr_m; Mutex cerr_m;
FILE* logf; FILE* logf;
priority_t loglevel; priority_t loglevel;
Mutex logger_m; Mutex logger_m;
}; };
class Logger_error : public runtime_error {
public:
Logger_error(const string& s)
: runtime_error(s) { }
};
} }
#endif // LIBSOCKTHREAD_LOGGER_HPP #endif // LIBSOCKTHREAD_LOGGER_HPP

View File

@@ -44,7 +44,7 @@ string& Time::utc(string &s) const
tm = gmtime(&unixtime); tm = gmtime(&unixtime);
char t[21]; char t[21];
strftime(t, sizeof t, "%Y-%m-%d %H:%M:%SZ", tm); strftime(t, sizeof t, "%Y-%m-%dT%H:%M:%SZ", tm);
return s = t; return s = t;
} }