[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( &timestamp);
-	struct timeval tp; gettimeofday( &tp, nullptr);
-	strftime( timestampbuf, 31, "%F %T", localtime( &timestamp));
-	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( &timestamp);
-	struct timeval tp; gettimeofday( &tp, nullptr);
-	strftime( timestampbuf, 31, "%F %T", localtime( &timestamp));
-	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