[med-svn] [aghermann] 01/60: log-facility is here
andrei zavada
hmmr-guest at alioth.debian.org
Mon Nov 4 23:49:50 UTC 2013
This is an automated email from the git hooks/post-receive script.
hmmr-guest pushed a commit to branch WIP
in repository aghermann.
commit 6dfde50f6a9046e823fc5d4b09ecdce7dcc7043f
Author: Andrei Zavada <johnhommer at gmail.com>
Date: Sun Sep 29 02:35:16 2013 +0300
log-facility is here
---
upstream/src/aghermann/globals.cc | 30 ++++-
upstream/src/aghermann/globals.hh | 9 ++
upstream/src/common/Makefile.am | 2 +
upstream/src/common/libcommon.cc | 50 ++++----
upstream/src/common/log-facility.cc | 215 +++++++++++++++++------------------
upstream/src/common/log-facility.hh | 93 +++++++--------
upstream/src/common/string.hh | 6 +-
7 files changed, 224 insertions(+), 181 deletions(-)
diff --git a/upstream/src/aghermann/globals.cc b/upstream/src/aghermann/globals.cc
index 3da9cfe..514dae4 100644
--- a/upstream/src/aghermann/globals.cc
+++ b/upstream/src/aghermann/globals.cc
@@ -10,6 +10,8 @@
*/
+#include <cstdarg>
+#include <cassert>
#include <sys/time.h>
#include <gsl/gsl_rng.h>
@@ -25,6 +27,8 @@
#endif
using namespace std;
+using namespace agh::global;
+
gsl_rng *agh::global::rng = nullptr;
@@ -51,9 +55,14 @@ init()
#ifdef _OPENMP
// 2. omp
{
- agh::global::num_procs = omp_get_max_threads();
+ num_procs = omp_get_max_threads();
}
#endif
+
+ // 3. log facility
+ {
+ default_log_facility = new agh::log::CLogFacility ("-");
+ }
}
@@ -63,8 +72,27 @@ fini()
{
gsl_rng_free( rng);
rng = nullptr;
+ delete default_log_facility;
+ default_log_facility = nullptr;
+}
+
+
+
+agh::log::CLogFacility* agh::global::default_log_facility;
+
+void
+agh::global::
+log( agh::log::TLevel level, const char* issuer, const char* fmt, ...)
+{
+ assert (default_log_facility);
+ va_list ap;
+ va_start (ap, fmt);
+ default_log_facility -> vmsg( level, issuer, fmt, ap);
+ va_end (ap);
}
+
+
// Local Variables:
// Mode: c++
// indent-tabs-mode: nil
diff --git a/upstream/src/aghermann/globals.hh b/upstream/src/aghermann/globals.hh
index da937bd..f0f5f52 100644
--- a/upstream/src/aghermann/globals.hh
+++ b/upstream/src/aghermann/globals.hh
@@ -13,6 +13,7 @@
#define AGH_AGHERMANN_GLOBALS_H_
#include <gsl/gsl_rng.h>
+#include "common/log-facility.hh"
#if HAVE_CONFIG_H && !defined(VERSION)
# include "config.h"
@@ -27,6 +28,14 @@ extern gsl_rng *rng;
extern int num_procs;
+extern agh::log::CLogFacility* default_log_facility;
+void log( agh::log::TLevel, const char* issuer, const char* fmt, ...) __attribute__ ((format (printf, 3, 4)));
+
+#define LOG_DEBUG(...) do agh::global::log( agh::log::TLevel::debug, agh::str::sasprintf("%s:%zu", __FILE__, __LINE__).c_str(), __VA_ARGS__); while (0)
+#define LOG_INFO(...) do agh::global::log( agh::log::TLevel::info, agh::str::sasprintf("%s:%zu", __FILE__, __LINE__).c_str(), __VA_ARGS__); while (0)
+#define LOG_WARN(...) do agh::global::log( agh::log::TLevel::warning, agh::str::sasprintf("%s:%zu", __FILE__, __LINE__).c_str(), __VA_ARGS__); while (0)
+#define LOG_ERROR(...) do agh::global::log( agh::log::TLevel::error, agh::str::sasprintf("%s:%zu", __FILE__, __LINE__).c_str(), __VA_ARGS__); while (0)
+
void init();
void fini();
diff --git a/upstream/src/common/Makefile.am b/upstream/src/common/Makefile.am
index 7a24aec..db60389 100644
--- a/upstream/src/common/Makefile.am
+++ b/upstream/src/common/Makefile.am
@@ -13,5 +13,7 @@ liba_a_SOURCES := \
lang.hh \
libcommon.cc \
string.hh \
+ log-facility.cc \
+ log-facility.hh \
subject_id.cc \
subject_id.hh
diff --git a/upstream/src/common/libcommon.cc b/upstream/src/common/libcommon.cc
index 43a3649..c11719a 100644
--- a/upstream/src/common/libcommon.cc
+++ b/upstream/src/common/libcommon.cc
@@ -33,6 +33,37 @@
using namespace std;
+string
+agh::str::
+svasprintf( const char* fmt, va_list ap)
+{
+ char *_;
+ if (vasprintf( &_, fmt, ap) <= 0)
+ abort();
+ string ret {_};
+ free( (void*)_);
+ return move(ret);
+}
+
+
+
+string
+agh::str::
+sasprintf( const char* fmt, ...)
+{
+ char *_;
+ va_list ap;
+ va_start (ap, fmt);
+ if (vasprintf( &_, fmt, ap) <= 0)
+ abort();
+ va_end (ap);
+
+ string ret {_};
+ free( (void*)_);
+ return move(ret);
+}
+
+
string
agh::str::
@@ -60,25 +91,6 @@ pad( const string& r0, size_t to)
-
-string
-agh::str::
-sasprintf( const char* fmt, ...)
-{
- char *_;
- va_list ap;
- va_start (ap, fmt);
- if (vasprintf( &_, fmt, ap) <= 0)
- abort();
- va_end (ap);
-
- string ret {_};
- free( (void*)_);
- return move(ret);
-}
-
-
-
list<string>
agh::str::
tokens_trimmed( const string& s_, const char* sep)
diff --git a/upstream/src/common/log-facility.cc b/upstream/src/common/log-facility.cc
index be7fc86..0339e19 100644
--- a/upstream/src/common/log-facility.cc
+++ b/upstream/src/common/log-facility.cc
@@ -1,145 +1,142 @@
/*
- * Author: Andrei Zavada <johnhommer at gmail.com>
+ * File name: common/log-facility.cc
+ * Project: Aghermann
+ * Author: Andrei Zavada <johnhommer at gmail.com>
+ * Initial version: 2009-06-28 (in aghermann since 2013-09-28)
*
- * License: GPL-2+
- *
- * Initial version: 2009-06-28
+ * Purpose: Simple log facility
*
+ * License: GPL
*/
#include <sys/time.h>
#include <cstdarg>
#include <cstring>
#include <cmath>
-#include <fstream>
+#include <stdexcept>
+#include <gsl/gsl_math.h>
+#include "string.hh"
-#include "config.h"
+#if HAVE_CONFIG_H && !defined(VERSION)
+# include "config.h"
+#endif
#include "log-facility.hh"
using namespace std;
+using namespace agh::log;
-Stilton::CLogFacility::
-CLogFacility( const char *log_fname,
- int inlog_threshold,
- int instdout_tee_threshold,
- unsigned short insec_dec_place,
- int bits,
- size_t buf_size)
- : status (bits),
- log_threshold (inlog_threshold),
- stdout_tee_threshold (instdout_tee_threshold),
- sec_dec_places (insec_dec_place)
-{
- _line_buf = new char[_buf_size = buf_size];
- if ( log_fname && strlen(log_fname) ) {
- _log_fname = string(log_fname);
- _log_strm.open( log_fname);
- unitbuf( _log_strm);
- }
-}
-
-Stilton::CLogFacility::
-~CLogFacility()
+const char*
+agh::log::
+level_s( TLevel l)
{
- if ( _log_fname.size() )
- _log_strm.close();
- delete[] _line_buf;
+ switch (l) {
+ case TLevel::debug : return "DEBUG";
+ case TLevel::info : return "INFO";
+ case TLevel::warning: return "WARN";
+ case TLevel::error : return "ERROR";
+ case TLevel::self : return "info";
+ default: return "eh?";
+ }
}
-void
-Stilton::CLogFacility::
-msg( int vrb, const char *client_name, const char* fmt, ...)
+CLogFacility::
+CLogFacility( const string& log_fname,
+ TLevel level_, bool compact_repeated_messages_,
+ unsigned short sec_dec_places_)
+ : level (level_),
+ compact_repeated_messages (compact_repeated_messages_),
+ sec_dec_places (sec_dec_places_),
+ _repeating_last (0)
{
- va_list ap;
- va_start (ap, fmt);
- msgv( vrb, client_name, fmt, ap);
- va_end (ap);
+ if ( sec_dec_places > 8 )
+ throw invalid_argument ("Seconds decimal places too big (>8)");
+ if ( log_fname == "-" )
+ _f = stdout;
+ else if ( !(_f = fopen( log_fname.c_str(), "w")) )
+ throw runtime_error ("Failed to open log file for writing");
+ msg( level, "log-facility", "init");
}
-
-void
-Stilton::CLogFacility::
-msgv( int vrb, const char *client_name, const char* fmt, va_list ap)
+CLogFacility::
+~CLogFacility()
{
-// if ( status & STILTON_LOG_NOLOCK )
-// boost::interprocess::scoped_lock<boost::interprocess::interprocess_mutex> L( _log_lock);
-
- if ( log_threshold < vrb && stdout_tee_threshold < vrb )
- return;
-
- char timestampbuf[32];
- time_t timestamp; time( ×tamp);
- struct timeval tp; gettimeofday( &tp, nullptr);
- strftime( timestampbuf, 31, "%F %T", localtime( ×tamp));
- char secfracbuf[sec_dec_places+3];
- snprintf( secfracbuf, sec_dec_places+2, ".%0*u", sec_dec_places,
- (unsigned)round( tp.tv_usec / pow( 10., 6-sec_dec_places-1)));
-
- vsnprintf( _line_buf, _buf_size, fmt, ap);
-
- char *line = strtok( _line_buf, "\n");
- do {
- if ( vrb < 0 )
- printf( "%s%sError: %s\n", client_name ? client_name : "", (client_name && strlen(client_name)) ? ": " : "", line);
- else if ( stdout_tee_threshold >= vrb )
- printf( "%s%s%s\n", client_name ? client_name : "", (client_name && strlen(client_name)) ? ": " : "", line);
-
- if ( log_threshold >= vrb && _log_fname.size() )
- _log_strm << timestampbuf << (sec_dec_places > 0 ? secfracbuf : "") << ' '
- << client_name << ": "
- << (vrb < 0 ? "Error: " : "") << line << endl;
- } while ( (line = strtok( nullptr, "\n")) );
-
- if ( _log_fname.size() )
- _log_strm.flush();
+ msg( level, "log-facility", "closing"); // will cause any withheld "above message repeated" message to be printed
+ if ( _f != stdout )
+ fclose(_f);
}
-// a one-liner, possibly unterminated by \n
void
-Stilton::CLogFacility::
-msg_( int vrb, const char *client_name, const char* fmt, ...)
+CLogFacility::
+msg( TLevel this_level, const char *issuer, const char* fmt, ...)
{
- va_list ap;
- va_start (ap, fmt);
- msgv_( vrb, client_name, fmt, ap);
- va_end (ap);
+ va_list ap;
+ va_start (ap, fmt);
+ vmsg( this_level, issuer, fmt, ap);
+ va_end (ap);
}
+
void
-Stilton::CLogFacility::
-msgv_( int vrb, const char *client_name, const char* fmt, va_list ap)
+CLogFacility::
+vmsg( TLevel this_level, const char *issuer, const char* fmt, va_list ap)
{
-// if ( status & STILTON_LOG_NOLOCK )
-// boost::interprocess::scoped_lock<boost::interprocess::interprocess_mutex> L( _log_lock);
-
- if ( log_threshold < vrb && stdout_tee_threshold < vrb )
- return;
-
- char timestampbuf[32];
- time_t timestamp; time( ×tamp);
- struct timeval tp; gettimeofday( &tp, nullptr);
- strftime( timestampbuf, 31, "%F %T", localtime( ×tamp));
- char secfracbuf[sec_dec_places+3];
- snprintf( secfracbuf, sec_dec_places+2, ".%0*u", sec_dec_places,
- (unsigned)round( tp.tv_usec / pow( 10., 6-sec_dec_places-1)));
-
- vsnprintf( _line_buf, _buf_size, fmt, ap);
-
- if ( vrb < 0 )
- printf( "%s%sError: %s", client_name ? client_name : "", (client_name && strlen(client_name)) ? ": " : "", _line_buf);
- else if ( stdout_tee_threshold >= vrb )
- printf( "%s%s%s", client_name ? client_name : "", (client_name && strlen(client_name)) ? ": " : "", _line_buf);
-
- if ( log_threshold >= vrb && _log_fname.size() )
- _log_strm << timestampbuf << (sec_dec_places > 0 ? secfracbuf : "") << ' '
- << client_name << ": "
- << (vrb < 0 ? "Error: " : "") << _line_buf << endl;
+ if ( level > this_level && this_level != TLevel::self )
+ return;
+
+ char timestampbuf[32 + 8 + 3];
+ {
+ struct timeval tp;
+ gettimeofday( &tp, nullptr);
+ _last_tp = tp;
+ size_t n = strftime( timestampbuf, 31, "%F %T", localtime( &tp.tv_sec));
+ snprintf( timestampbuf+n, sec_dec_places+2, ".%0*u", sec_dec_places,
+ (unsigned)round( tp.tv_usec / gsl_pow_int( 10., 6-sec_dec_places-1)));
+ }
+
+ string the_line = agh::str::svasprintf( fmt, ap);
+
+ // treat multiline message as a series of
+ if ( compact_repeated_messages && the_line == _last_line )
+ ++_repeating_last; // defer printing
+ else {
+ if ( _repeating_last ) {
+ fprintf( _f, "%s (above message repeated %zu time(s))\n", timestampbuf, _repeating_last);
+ _repeating_last = 0;
+ }
+
+ // puncturing this_line will incidentally cause any multiline messages to never match _last_line,
+ // -- but it's just ok, because it avoids confusion as to what exactly "above message" can refer to
+ char *line = strtok( &the_line[0], "\n");
+ string to_print;
+ size_t mline = 0;
+ do {
+ if ( mline > 0 )
+ fprintf( _f,
+ "%s %s %*zu %s\n",
+ timestampbuf, level_s(this_level),
+ strlen(issuer), mline,
+ line);
+ else
+ fprintf( _f,
+ "%s %s %s %s\n",
+ timestampbuf, level_s(this_level),
+ issuer,
+ line);
+ ++mline;
+ } while ( (line = strtok( nullptr, "\n")) );
+ }
+
+ _last_line = the_line;
}
-
-// eof
+// Local Variables:
+// Mode: c++
+// indent-tabs-mode: nil
+// tab-width: 8
+// c-basic-offset: 8
+// End:
diff --git a/upstream/src/common/log-facility.hh b/upstream/src/common/log-facility.hh
index e48c807..4188453 100644
--- a/upstream/src/common/log-facility.hh
+++ b/upstream/src/common/log-facility.hh
@@ -1,75 +1,68 @@
/*
- * Author: Andrei Zavada <johnhommer at gmail.com>
+ * File name: common/log-facility.hh
+ * Project: Aghermann
+ * Author: Andrei Zavada <johnhommer at gmail.com>
+ * Initial version: 2009-06-28 (in aghermann since 2013-09-28)
*
- * License: GPL-2+
- *
- * Initial version: 2009-06-28
+ * Purpose: Simple log facility
*
+ * License: GPL
*/
-#ifndef STILTON_LOG_FACILITY_H
-#define STILTON_LOG_FACILITY_H
+#ifndef AGH_COMMON_LOG_FACILITY_H
+#define AGH_COMMON_LOG_FACILITY_H
#include <cstdarg>
#include <fstream>
-//#include <boost/interprocess/sync/interprocess_mutex.hpp>
-//#include <boost/interprocess/sync/interprocess_condition.hpp>
-
-
-namespace Stilton {
-
using namespace std;
-using namespace Stilton;
-// bitwise OR this with CLogFacility::status to prevent locking even if supported
-#define STILTON_LOG_NOLOCK 1
+namespace agh {
+namespace log {
+
+enum TLevel {
+ self, // reserved for log-facility itself
+ error = 1, warning, info, debug
+};
+const char* level_s( TLevel);
class CLogFacility {
public:
- CLogFacility( const char *log_fname,
- int log_threshold = 4,
- int stdout_tee_threshold = 2,
- unsigned short sec_dec_places = 2,
- int bits = 0,
- size_t buf_size = 2048);
-
- int status;
-
- int log_threshold,
- stdout_tee_threshold;
- unsigned short
- sec_dec_places;
- // full-featured; always terminating lines with a \n
- void msg( int vrb, const char *client_name, const char* fmt, ...);
- void msgv( int vrb, const char *client_name, const char* fmt, va_list);
- // raw output: no parsing, not timestamping each line
- void msg_( int vrb, const char *client_name, const char* fmt, ...);
- void msgv_( int vrb, const char *client_name, const char* fmt, va_list);
-
- const char *log_fname() const
- { return _log_fname.c_str(); }
- size_t buf_size() const
- { return _buf_size; }
-
+ CLogFacility( const string& log_fname, // "-" means stdout
+ TLevel level_ = TLevel::info, // print messages of level up and including this
+ bool compact_repeated_messages_ = true,
+ unsigned short sec_dec_places = 2);
~CLogFacility();
+ void msg( TLevel, const char* issuer, const char* fmt, ...) __attribute__ ((format (printf, 4, 5)));
+ void vmsg( TLevel, const char* issuer, const char* fmt, va_list);
+
+ TLevel level;
+ bool compact_repeated_messages:1;
+
private:
- string _log_fname;
- size_t _buf_size;
- ofstream
- _log_strm;
- char
- *_line_buf;
-// boost::interprocess::interprocess_mutex
-// _log_lock;
+ string _log_fname;
+ FILE* _f;
+ unsigned short
+ sec_dec_places;
+
+ string _last_line;
+ struct timeval
+ _last_tp;
+ size_t _repeating_last;
};
+#define LOGHERE()
-}
+}} // namespace agh::log
#endif
-// EOF
+// Local Variables:
+// Mode: c++
+// indent-tabs-mode: nil
+// tab-width: 8
+// c-basic-offset: 8
+// End:
diff --git a/upstream/src/common/string.hh b/upstream/src/common/string.hh
index 3083168..bcd7645 100644
--- a/upstream/src/common/string.hh
+++ b/upstream/src/common/string.hh
@@ -9,9 +9,10 @@
* License: GPL
*/
-#ifndef _AGH_COMMON_STRING_H
-#define _AGH_COMMON_STRING_H
+#ifndef AGH_COMMON_STRING_H_
+#define AGH_COMMON_STRING_H_
+#include <cstdarg>
#include <cstring>
#include <string>
#include <list>
@@ -31,6 +32,7 @@ enum class TStrCmpCaseOption {
};
string sasprintf( const char* fmt, ...) __attribute__ ((format (printf, 1, 2)));
+string svasprintf( const char* fmt, va_list aaa);
string trim( const string& r0);
string pad( const string& r0, size_t to);
--
Alioth's /git/debian-med/git-commit-notice on /srv/git.debian.org/git/debian-med/aghermann.git
More information about the debian-med-commit
mailing list