ewmscp  ..
syslogstream.h
Go to the documentation of this file.
1 #ifndef __syslogstream_h__
2 #define __syslogstream_h__
3 
4 #include <iostream>
5 #include <fstream>
6 #include <syslog.h>
7 #include <vector>
8 
9 namespace logstream {
10  enum class level {
11  emerg = LOG_EMERG,
12  alert = LOG_ALERT,
13  crit = LOG_CRIT,
14  err = LOG_ERR,
15  warning = LOG_WARNING,
16  notice = LOG_NOTICE,
17  info = LOG_INFO,
18  debug = LOG_DEBUG
19  };
20  class namedLevel {
21  std::string name;
23  namedLevel(const std::string&aName, level aLevel): name(aName), Level(aLevel) {}
24  static const std::vector<namedLevel>& getNameList() {
25 #define mapItem(s) {#s,static_cast<level>(LOG_##s)}
26  static decltype(getNameList()) nameList {
27  mapItem(EMERG), mapItem(ALERT), mapItem(CRIT),
28  mapItem(ERR), mapItem(WARNING),
29  mapItem(NOTICE), mapItem(INFO),
30  mapItem(DEBUG)
31  };
32 #undef mapItem
33  return nameList;
34  }
35  public:
36  static level getLevelByName(const std::string& aName) {
37  for (const auto& l : getNameList()) {
38  if (l.name == aName) {
39  return l.Level;
40  }
41  }
42  throw std::runtime_error("unknown level name " + aName);
43  }
44  static const std::string& getNameByLevel(level aLevel) {
45  for (const auto& l : getNameList()) {
46  if (l.Level == aLevel) {
47  return l.name;
48  }
49  }
50  throw std::runtime_error("illegal level");
51  }
52  };
53 
54 
55  class syslogbuf : public std::streambuf {
56  protected:
57 
58  int overflow(int c = EOF) override {
59  if (c == '\n' || !c || c == EOF) {
60  if (message.size() != 0) {
61  syslog(static_cast<int>(currentLevel), "%s\n",
62  message.c_str());
64  }
65  message.clear();
66  if (c == EOF) {
67  return !c;
68  }
69  return c;
70  }
71  message.push_back(c);
72  return c;
73  }
74  std::string message;
77 
78  public:
79  ~syslogbuf() override {
80  overflow();
81  };
82  syslogbuf(const std::string& aLevel):
83  defaultLevel(namedLevel::getLevelByName(aLevel)),
85  void setLevel(level aLevel) {
86  currentLevel = aLevel;
87  }
88  };
89 
90  class logstream : public std::ostream {
91  protected:
93  public:
94  logstream(const std::string& aLevel) : std::ostream(&buffer), buffer(aLevel) {}
95  void setLevel(level aLevel) {
96  buffer.setLevel(aLevel);
97  }
98  };
99 
100  class provider {
101  std::ostream *stream;
102  std::ostream& defaultStream;
103  public:
104  provider(const std::string& name, std::ostream& aDefaultStream = std::cout) :
105  defaultStream(name == "std::cerr" ? std::cerr : aDefaultStream) {
106  if (name.empty() || name == "std::cerr") {
108  } else if (name.compare(0, 6, "syslog") == 0) {
109  auto defaultLevel = name.substr(6);
110  if (defaultLevel.empty()) {
111  defaultLevel = "INFO";
112  } else {
113  defaultLevel.erase(0, 1);
114  }
115  stream = new logstream(defaultLevel);
116  } else {
117  stream = new std::ofstream(name, std::ios::out | std::ios::ate);
118  }
119  }
121  if (stream != &defaultStream) {
122  delete stream;
123  }
124  }
125  std::ostream& getStream() {
126  return *stream;
127  }
128  };
129 } // end of logstream namespace
130 inline std::ostream& operator<<(std::ostream& stream, const logstream::level& aLevel) {
131  auto logStream = dynamic_cast<logstream::logstream*>(&stream);
132  if (logStream != nullptr) {
133  logStream->setLevel(aLevel);
134  } else {
135  stream << logstream::namedLevel::getNameByLevel(aLevel);
136  stream << ": ";
137  }
138  return stream;
139 }
140 #endif
logstream::syslogbuf::currentLevel
level currentLevel
Definition: syslogstream.h:76
logstream::logstream::setLevel
void setLevel(level aLevel)
Definition: syslogstream.h:95
logstream::provider::~provider
~provider()
Definition: syslogstream.h:120
logstream::namedLevel::name
std::string name
Definition: syslogstream.h:21
mapItem
#define mapItem(s)
logstream::namedLevel::getNameList
static const std::vector< namedLevel > & getNameList()
Definition: syslogstream.h:24
logstream::level::info
@ info
logstream::logstream::buffer
syslogbuf buffer
Definition: syslogstream.h:92
logstream::syslogbuf::message
std::string message
Definition: syslogstream.h:74
logstream::logstream
Definition: syslogstream.h:90
logstream::provider::stream
std::ostream * stream
Definition: syslogstream.h:101
logstream::provider::provider
provider(const std::string &name, std::ostream &aDefaultStream=std::cout)
Definition: syslogstream.h:104
logstream::level::warning
@ warning
logstream::level::err
@ err
logstream::provider
Definition: syslogstream.h:100
logstream::provider::getStream
std::ostream & getStream()
Definition: syslogstream.h:125
logstream::syslogbuf::setLevel
void setLevel(level aLevel)
Definition: syslogstream.h:85
logstream::level::notice
@ notice
logstream::level::alert
@ alert
logstream::syslogbuf
Definition: syslogstream.h:55
logstream
Definition: syslogstream.h:9
logstream::namedLevel::Level
level Level
Definition: syslogstream.h:22
logstream::level::crit
@ crit
logstream::namedLevel::getNameByLevel
static const std::string & getNameByLevel(level aLevel)
Definition: syslogstream.h:44
operator<<
std::ostream & operator<<(std::ostream &stream, const logstream::level &aLevel)
Definition: syslogstream.h:130
logstream::provider::defaultStream
std::ostream & defaultStream
Definition: syslogstream.h:102
logstream::namedLevel::namedLevel
namedLevel(const std::string &aName, level aLevel)
Definition: syslogstream.h:23
logstream::level
level
Definition: syslogstream.h:10
logstream::syslogbuf::~syslogbuf
~syslogbuf() override
Definition: syslogstream.h:79
logstream::level::debug
@ debug
logstream::level::emerg
@ emerg
logstream::syslogbuf::defaultLevel
level defaultLevel
Definition: syslogstream.h:75
logstream::namedLevel::getLevelByName
static level getLevelByName(const std::string &aName)
Definition: syslogstream.h:36
logstream::syslogbuf::syslogbuf
syslogbuf(const std::string &aLevel)
Definition: syslogstream.h:82
logstream::namedLevel
Definition: syslogstream.h:20
logstream::syslogbuf::overflow
int overflow(int c=EOF) override
Definition: syslogstream.h:58
logstream::logstream::logstream
logstream(const std::string &aLevel)
Definition: syslogstream.h:94