diff --git a/qse/include/qse/si/App.hpp b/qse/include/qse/si/App.hpp index aa2b0efe..0f3eac44 100644 --- a/qse/include/qse/si/App.hpp +++ b/qse/include/qse/si/App.hpp @@ -36,21 +36,23 @@ #include #include +#include + ///////////////////////////////// QSE_BEGIN_NAMESPACE(QSE) ///////////////////////////////// #define QSE_APP_LOG_ENABLED(app, mask) (((app)->getLogMask() & (mask)) == (mask)) -#define QSE_APP_LOG0(app, mask, fmt) do { if (QSE_APP_LOG_ENABLED(app, (mask))) app->logfmt((mask), fmt); } while(0) -#define QSE_APP_LOG1(app, mask, fmt, a1) do { if (QSE_APP_LOG_ENABLED(app, (mask))) app->logfmt((mask), fmt, a1); } while(0) -#define QSE_APP_LOG2(app, mask, fmt, a1, a2) do { if (QSE_APP_LOG_ENABLED(app, (mask))) app->logfmt((mask), fmt, a1, a2); } while(0) -#define QSE_APP_LOG3(app, mask, fmt, a1, a2, a3) do { if (QSE_APP_LOG_ENABLED(app, (mask))) app->logfmt((mask), fmt, a1, a2, a3); } while(0) -#define QSE_APP_LOG4(app, mask, fmt, a1, a2, a3, a4) do { if (QSE_APP_LOG_ENABLED(app, (mask))) app->logfmt((mask), fmt, a1, a2, a3, a4); } while(0) -#define QSE_APP_LOG5(app, mask, fmt, a1, a2, a3, a4, a5) do { if (QSE_APP_LOG_ENABLED(app, (mask))) app->logfmt((mask), fmt, a1, a2, a3, a4, a5); } while(0) -#define QSE_APP_LOG6(app, mask, fmt, a1, a2, a3, a4, a5, a6) do { if (QSE_APP_LOG_ENABLED(app, (mask))) app->logfmt((mask), fmt, a1, a2, a3, a4, a5, a6); } while(0) -#define QSE_APP_LOG7(app, mask, fmt, a1, a2, a3, a4, a5, a6, a7) do { if (QSE_APP_LOG_ENABLED(app, (mask))) app->logfmt((mask), fmt, a1, a2, a3, a4, a5, a6, a7); } while(0) -#define QSE_APP_LOG8(app, mask, fmt, a1, a2, a3, a4, a5, a6, a7, a8) do { if (QSE_APP_LOG_ENABLED(app, (mask))) app->logfmt((mask), fmt, a1, a2, a3, a4, a5, a6, a7, a8); } while(0) -#define QSE_APP_LOG9(app, mask, fmt, a1, a2, a3, a4, a5, a6, a7, a8, a9) do { if (QSE_APP_LOG_ENABLED(app, (mask))) app->logfmt((mask), fmt, a1, a2, a3, a4, a5, a6, a7, a8, a9); } while(0) +#define QSE_APP_LOG0(app, mask, fmt) do { if (QSE_APP_LOG_ENABLED(app, (mask))) (app)->logfmt((mask), fmt); } while(0) +#define QSE_APP_LOG1(app, mask, fmt, a1) do { if (QSE_APP_LOG_ENABLED(app, (mask))) (app)->logfmt((mask), fmt, a1); } while(0) +#define QSE_APP_LOG2(app, mask, fmt, a1, a2) do { if (QSE_APP_LOG_ENABLED(app, (mask))) (app)->logfmt((mask), fmt, a1, a2); } while(0) +#define QSE_APP_LOG3(app, mask, fmt, a1, a2, a3) do { if (QSE_APP_LOG_ENABLED(app, (mask))) (app)->logfmt((mask), fmt, a1, a2, a3); } while(0) +#define QSE_APP_LOG4(app, mask, fmt, a1, a2, a3, a4) do { if (QSE_APP_LOG_ENABLED(app, (mask))) (app)->logfmt((mask), fmt, a1, a2, a3, a4); } while(0) +#define QSE_APP_LOG5(app, mask, fmt, a1, a2, a3, a4, a5) do { if (QSE_APP_LOG_ENABLED(app, (mask))) (app)->logfmt((mask), fmt, a1, a2, a3, a4, a5); } while(0) +#define QSE_APP_LOG6(app, mask, fmt, a1, a2, a3, a4, a5, a6) do { if (QSE_APP_LOG_ENABLED(app, (mask))) (app)->logfmt((mask), fmt, a1, a2, a3, a4, a5, a6); } while(0) +#define QSE_APP_LOG7(app, mask, fmt, a1, a2, a3, a4, a5, a6, a7) do { if (QSE_APP_LOG_ENABLED(app, (mask))) (app)->logfmt((mask), fmt, a1, a2, a3, a4, a5, a6, a7); } while(0) +#define QSE_APP_LOG8(app, mask, fmt, a1, a2, a3, a4, a5, a6, a7, a8) do { if (QSE_APP_LOG_ENABLED(app, (mask))) (app)->logfmt((mask), fmt, a1, a2, a3, a4, a5, a6, a7, a8); } while(0) +#define QSE_APP_LOG9(app, mask, fmt, a1, a2, a3, a4, a5, a6, a7, a8, a9) do { if (QSE_APP_LOG_ENABLED(app, (mask))) (app)->logfmt((mask), fmt, a1, a2, a3, a4, a5, a6, a7, a8, a9); } while(0) class App: public Uncopyable, public Types, public Mmged { @@ -214,7 +216,7 @@ private: qse_cmgr_t* _cmgr; struct log_t { - log_t (App* app): mask(0), last_mask(0), len(0), mtx(app->getMmgr()) + log_t (App* app): mask(0), last_mask(0), len(0), mtx(app->getMmgr()), logger(QSE_NULL) { } @@ -222,6 +224,7 @@ private: qse_size_t len; qse_char_t buf[256]; QSE::Mutex mtx; + qse_log_t* logger; } _log; static int set_signal_handler_no_mutex (int sig, SignalHandler sighr); diff --git a/qse/include/qse/si/log.h b/qse/include/qse/si/log.h index b6aac2b9..a8ce28fd 100644 --- a/qse/include/qse/si/log.h +++ b/qse/include/qse/si/log.h @@ -54,6 +54,10 @@ #define QSE_LOG_NOTICE (1 << 5) #define QSE_LOG_INFO (1 << 6) #define QSE_LOG_DEBUG (1 << 7) +#define QSE_LOG_ALL_PRIORITIES \ + (QSE_LOG_PANIC | QSE_LOG_ALERT | QSE_LOG_CRITICAL | \ + QSE_LOG_ERROR | QSE_LOG_WARNING | QSE_LOG_NOTICE | \ + QSE_LOG_INFO | QSE_LOG_DEBUG) /* options */ #define QSE_LOG_KEEP_FILE_OPEN (1 << 13) diff --git a/qse/lib/si/App.cpp b/qse/lib/si/App.cpp index 62a6a289..8d2ea158 100644 --- a/qse/lib/si/App.cpp +++ b/qse/lib/si/App.cpp @@ -114,6 +114,13 @@ App::~App () QSE_CPP_NOEXCEPT QSE_ASSERT (this->_prev_app == QSE_NULL); g_app_top = this->_next_app; } + + + if (this->_log.logger) + { + qse_log_close (this->_log.logger); + this->_log.logger = QSE_NULL; + } } int App::daemonize (bool chdir_to_root, int fork_count, bool root_only) QSE_CPP_NOEXCEPT @@ -530,8 +537,15 @@ int App::guardProcess (const SignalSet& signals, qse_mtime_t guard_pause_ms, con int App::put_char_to_log_buf (qse_char_t c, void* ctx) { App* app = (App*)ctx; - if (app->_log.len >= QSE_COUNTOF(app->_log.buf) - 1) // -1 for the lien terminator appending in App::logfmtv() + + if (app->_log.len >= QSE_COUNTOF(app->_log.buf) - 1) { + if (app->_log.buf[app->_log.len - 1] != '\n') + { + /* no line ending - append a line terminator */ + app->_log.buf[app->_log.len++] = '\n'; + } + app->log_write (app->_log.last_mask, app->_log.buf, app->_log.len); app->_log.len = 0; } @@ -594,6 +608,22 @@ void App::logfmtv (int mask, const qse_char_t* fmt, va_list ap) // default log message output implementation void App::log_write (int mask, const qse_char_t* msg, qse_size_t len) { + if (!this->_log.logger) + { + qse_log_target_t target; + +// TODO: ... + QSE_MEMSET (&target, 0, QSE_SIZEOF(target)); + target.file = QSE_T("app.log"); + this->_log.logger = qse_log_open(this->getMmgr(), 0, QSE_T("app"), QSE_LOG_INCLUDE_PID | QSE_LOG_ALL_PRIORITIES | QSE_LOG_FILE | QSE_LOG_CONSOLE, &target); + } + + if (this->_log.logger) + { +// TOOD: add qse_log_write() which doesn't do formatting?? + // the last character is \n. qse_log_report() knows to terminate a line. so exclude it from reporting + qse_log_report (this->_log.logger, QSE_NULL, QSE_LOG_LOCAL0 | QSE_LOG_INFO, QSE_T("%.*js"), (int)(len - 1), msg); + } } diff --git a/qse/samples/si/tcpsvr01.cpp b/qse/samples/si/tcpsvr01.cpp index 6210816e..8c39ab62 100644 --- a/qse/samples/si/tcpsvr01.cpp +++ b/qse/samples/si/tcpsvr01.cpp @@ -70,7 +70,7 @@ public: case SIGHUP: // TODO: don't call stop() if this processs is a guardian // though it's no harm to call stop(). - qse_printf (QSE_T("requesting to stop server...app %p server %p - pid %d\n"), this, &this->server, (int)getpid()); + QSE_APP_LOG3 (this, MyApp::LOG_INFO | MyApp::LOG_TYPE_0, QSE_T("requesting to stop server...app %p server %p - pid %d\n"), this, &this->server, (int)getpid()); this->server.stop(); break; } @@ -86,7 +86,9 @@ public: signals.set (SIGUSR2); if (this->guardProcess(signals) > 0) { - qse_printf (QSE_T("Stareting server\n")); + this->setLogMask (MyApp::LOG_ALL_LEVELS | MyApp::LOG_ALL_TYPES); + + QSE_APP_LOG0 (this, MyApp::LOG_INFO | MyApp::LOG_TYPE_0, QSE_T("Stareting server\n")); this->server.setThreadStackSize (256000); return this->server.start (QSE_T("[::]:9998,0.0.0.0:9998")); } @@ -120,7 +122,7 @@ app2.acceptSignal (SIGINT); app4.neglectSignal (SIGINT); app3.neglectSignal (SIGINT); app2.neglectSignal (SIGINT); -qse_printf (QSE_T("END OF %d\n"), (int)getpid()); +QSE_APP_LOG1 (&app, MyApp::LOG_INFO | MyApp::LOG_TYPE_0, QSE_T("END OF %d\n"), (int)getpid()); return n; }