summaryrefslogtreecommitdiff
path: root/src/logger.cc
diff options
context:
space:
mode:
authorJoel Klinghed <the_jk@yahoo.com>2017-02-28 21:50:44 +0100
committerJoel Klinghed <the_jk@yahoo.com>2017-02-28 21:50:44 +0100
commitc029d90d1975e124d237605f1edb2be16bd05b5d (patch)
tree9df87ffb365354bdb74a969440b32c8304bdbcb7 /src/logger.cc
Initial commit
Diffstat (limited to 'src/logger.cc')
-rw-r--r--src/logger.cc130
1 files changed, 130 insertions, 0 deletions
diff --git a/src/logger.cc b/src/logger.cc
new file mode 100644
index 0000000..29dcb38
--- /dev/null
+++ b/src/logger.cc
@@ -0,0 +1,130 @@
+// -*- mode: c++; c-basic-offset: 2; -*-
+
+#include "common.hh"
+
+#ifndef _BSD_SOURCE
+#define _BSD_SOURCE
+#endif
+#ifndef _DEFAULT_SOURCE
+#define _DEFAULT_SOURCE
+#endif
+
+#include <cstdarg>
+#include <cstdio>
+#include <iostream>
+#include <memory>
+#include <syslog.h>
+
+#include "logger.hh"
+
+namespace {
+
+class LoggerStdErr : public Logger {
+public:
+ void out(Level UNUSED(lvl), char const* format, ...) override {
+ char* tmp;
+ va_list args;
+ va_start(args, format);
+ auto ret = vasprintf(&tmp, format, args);
+ va_end(args);
+ if (ret == -1) return;
+ std::cerr << tmp << std::endl;
+ free(tmp);
+ }
+};
+
+class LoggerSyslog : public Logger {
+public:
+ LoggerSyslog(std::string const& name) {
+ openlog(name.c_str(), LOG_PID, LOG_DAEMON);
+ }
+
+ ~LoggerSyslog() override {
+ closelog();
+ }
+
+ void out(Level lvl, char const* format, ...) override {
+ va_list args;
+ va_start(args, format);
+ vsyslog(lvl2prio(lvl), format, args);
+ va_end(args);
+ }
+
+private:
+ static int lvl2prio(Level lvl) {
+ switch (lvl) {
+ case ERR:
+ return LOG_ERR;
+ case WARN:
+ return LOG_WARNING;
+ case INFO:
+ return LOG_INFO;
+ }
+ assert(false);
+ return LOG_INFO;
+ }
+};
+
+class LoggerFile : public Logger {
+public:
+ LoggerFile()
+ : fh_(nullptr) {
+ }
+
+ bool open(std::string const& path) {
+ if (fh_) fclose(fh_);
+ fh_ = fopen(path.c_str(), "a");
+ return fh_ != NULL;
+ }
+
+ ~LoggerFile() override {
+ if (fh_) fclose(fh_);
+ }
+
+ void out(Level lvl, char const* format, ...) override {
+ fputs(lvl2str(lvl), fh_);
+ fwrite(": ", 1, 2, fh_);
+ va_list args;
+ va_start(args, format);
+ vfprintf(fh_, format, args);
+ va_end(args);
+ fputc('\n', fh_);
+ }
+
+private:
+ static char const* lvl2str(Level lvl) {
+ switch (lvl) {
+ case ERR:
+ return "Error";
+ case WARN:
+ return "Warning";
+ case INFO:
+ return "Info";
+ }
+ assert(false);
+ return "Info";
+ }
+
+ FILE* fh_;
+};
+
+} // namespace
+
+// static
+Logger* Logger::create_stderr() {
+ return new LoggerStdErr();
+}
+
+// static
+Logger* Logger::create_syslog(std::string const& name) {
+ return new LoggerSyslog(name);
+}
+
+// static
+Logger* Logger::create_file(std::string const& path) {
+ std::unique_ptr<LoggerFile> ret(new LoggerFile());
+ if (ret->open(path)) {
+ return ret.release();
+ }
+ return nullptr;
+}