Got rid of std::string construction.
More unification on syslog,stderr,fd.
Signed-off-by: Adam Kupczyk <akupczyk@mirantis.com>
#include "common/PrebufferedStreambuf.h"
-
+#include <string.h>
PrebufferedStreambuf::PrebufferedStreambuf(char *buf, size_t len)
: m_buf(buf), m_buf_len(len)
{
return std::string(m_buf, this->pptr() - m_buf);
}
}
+// returns current size of content
+size_t PrebufferedStreambuf::size() const
+{
+ if(m_overflow.size() == 0) {
+ return this->pptr() - m_buf;
+ } else {
+ return m_buf_len + m_overflow.size();
+ }
+}
+
+// extracts up to avail chars of content
+int PrebufferedStreambuf::snprintf(char* dst, size_t avail) const
+{
+ size_t o_size=m_overflow.size();
+ size_t len_a;
+ size_t len_b;
+ if(o_size>0){
+ len_a = m_buf_len;
+ len_b = o_size;
+ } else {
+ len_a = this->pptr() - m_buf;
+ len_b = 0;
+ }
+ if(avail > len_a + len_b ) {
+ memcpy(dst, m_buf, len_a);
+ memcpy(dst + m_buf_len, m_overflow.c_str(), len_b);
+ dst[len_a + len_b] = 0;
+ } else {
+ if(avail > len_a ) {
+ memcpy(dst, m_buf, len_a);
+ memcpy(dst + m_buf_len, m_overflow.c_str(), avail - len_a - 1);
+ dst[avail - 1] = 0;
+ } else {
+ memcpy(dst, m_buf, avail - 1);
+ dst[avail - 1] = 0;
+ }
+ }
+ return len_a + len_b;
+}
/// return a string copy (inefficiently)
std::string get_str() const;
-};
+
+ // returns current size of content
+ size_t size() const;
+
+ // extracts up to avail chars of content
+ int snprintf(char* dst, size_t avail) const;
+};
#endif
time_t tt = sec();
localtime_r(&tt, &bdt);
- return snprintf(out, outlen,
+ return ::snprintf(out, outlen,
"%04d-%02d-%02d %02d:%02d:%02d.%06ld",
bdt.tm_year + 1900, bdt.tm_mon + 1, bdt.tm_mday,
bdt.tm_hour, bdt.tm_min, bdt.tm_sec, usec());
}
+ static int snprintf(char *out, int outlen, time_t tt) {
+ struct tm bdt;
+ localtime_r(&tt, &bdt);
+
+ return ::snprintf(out, outlen,
+ "%04d-%02d-%02d %02d:%02d:%02d",
+ bdt.tm_year + 1900, bdt.tm_mon + 1, bdt.tm_mday,
+ bdt.tm_hour, bdt.tm_min, bdt.tm_sec);
+ }
+
static int parse_date(const string& date, uint64_t *epoch, uint64_t *nsec,
string *out_date=NULL, string *out_time=NULL) {
struct tm tm;
std::string get_str() const {
return m_streambuf.get_str();
}
+
+ // returns current size of content
+ size_t size() const {
+ return m_streambuf.size();
+ }
+
+ // extracts up to avail chars of content
+ int snprintf(char* dst, size_t avail) const {
+ return m_streambuf.snprintf(dst, avail);
+ }
};
}
void Log::_flush(EntryQueue *t, EntryQueue *requeue, bool crash)
{
Entry *e;
- char buf[80];
while ((e = t->dequeue()) != NULL) {
unsigned sub = e->m_subsys;
bool do_stderr = m_stderr_crash >= e->m_prio && should_log;
if (do_fd || do_syslog || do_stderr) {
- int buflen = 0;
+ size_t buflen = 0;
+ char buf[80 + e->size()];
if (crash)
buflen += snprintf(buf, sizeof(buf), "%6d> ", -t->m_len);
buflen += snprintf(buf + buflen, sizeof(buf)-buflen, " %lx %2d ",
(unsigned long)e->m_thread, e->m_prio);
- // FIXME: this is slow
- string s = e->get_str();
-
- if (do_fd) {
- int r = safe_write(m_fd, buf, buflen);
- if (r >= 0)
- r = safe_write(m_fd, s.data(), s.size());
- if (r >= 0)
- r = write(m_fd, "\n", 1);
- if (r < 0)
- cerr << "problem writing to " << m_log_file << ": " << cpp_strerror(r) << std::endl;
- }
+ buflen += e->snprintf(buf + buflen, sizeof(buf) - buflen - 1 );
+ if(buflen > sizeof(buf) - 1 ) //paranoid check, buf was declared to hold everything
+ buflen = sizeof(buf) - 1;
if (do_syslog) {
- syslog(LOG_USER, "%s%s", buf, s.c_str());
+ syslog(LOG_USER, "%s", buf);
}
if (do_stderr) {
- cerr << buf << s << std::endl;
+ cerr << buf << std::endl;
+ }
+ if (do_fd) {
+ buf[buflen-1]='\n';
+ buf[buflen]='\0';
+ int r=safe_write(m_fd, buf, buflen+1);
+ if (r < 0)
+ cerr << "problem writing to " << m_log_file << ": " << cpp_strerror(r) << std::endl;
}
}