Commit a549a4f4 authored by Pavel Vainerman's avatar Pavel Vainerman

(LogDB): added support write logfiles

parent 9f126dd9
...@@ -190,6 +190,18 @@ LogDB::LogDB( const string& name, int argc, const char* const* argv, const strin ...@@ -190,6 +190,18 @@ LogDB::LogDB( const string& name, int argc, const char* const* argv, const strin
if( !dbDisabled ) if( !dbDisabled )
l->signal_on_read().connect(sigc::mem_fun(this, &LogDB::addLog)); l->signal_on_read().connect(sigc::mem_fun(this, &LogDB::addLog));
auto lfile = sit.getProp("logfile");
if( !lfile.empty() )
{
l->logfile = make_shared<DebugStream>();
l->logfile->logFile(lfile, false);
l->logfile->level(Debug::ANY);
l->logfile->showDateTime(false);
l->logfile->showLogType(false);
l->logfile->disableOnScreen();
l->signal_on_read().connect(sigc::mem_fun(this, &LogDB::log2File));
}
// l->set(loop); // l->set(loop);
logservers.push_back(l); logservers.push_back(l);
...@@ -398,6 +410,14 @@ void LogDB::addLog( LogDB::Log* log, const string& txt ) ...@@ -398,6 +410,14 @@ void LogDB::addLog( LogDB::Log* log, const string& txt )
qbuf.emplace(q.str()); qbuf.emplace(q.str());
} }
//-------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------
void LogDB::log2File( LogDB::Log* log, const string& txt )
{
if( !log->logfile || !log->logfile->isOnLogFile() )
return;
log->logfile->any() << txt << endl;
}
//--------------------------------------------------------------------------------------------
size_t LogDB::getCountOfRecords( const std::string& logname ) size_t LogDB::getCountOfRecords( const std::string& logname )
{ {
ostringstream q; ostringstream q;
......
...@@ -54,6 +54,7 @@ namespace uniset ...@@ -54,6 +54,7 @@ namespace uniset
- \ref sec_LogDB_WEBSOCK - \ref sec_LogDB_WEBSOCK
- \ref sec_LogDB_DETAIL - \ref sec_LogDB_DETAIL
- \ref sec_LogDB_ADMIN - \ref sec_LogDB_ADMIN
- \ref sec_LogDB_LOGFILE
\section sec_LogDB_Comm Общее описание работы LogDB \section sec_LogDB_Comm Общее описание работы LogDB
...@@ -72,7 +73,7 @@ namespace uniset ...@@ -72,7 +73,7 @@ namespace uniset
<LogDB name="LogDB" ...> <LogDB name="LogDB" ...>
<logserver name="" ip=".." port=".." cmd=".." description=".."/> <logserver name="" ip=".." port=".." cmd=".." description=".."/>
<logserver name="" ip=".." port=".." cmd=".." description=".."/> <logserver name="" ip=".." port=".." cmd=".." description=".."/>
<logserver name="" ip=".." port=".." cmd=".."/> <logserver name="" ip=".." port=".." cmd=".." logfile=".."/>
</LogDB> </LogDB>
\endcode \endcode
...@@ -135,6 +136,10 @@ namespace uniset ...@@ -135,6 +136,10 @@ namespace uniset
Количество создаваемых websocket-ов можно ограничить при помощи параметр maxWebsockets (--prefix-ws-max). Количество создаваемых websocket-ов можно ограничить при помощи параметр maxWebsockets (--prefix-ws-max).
\section sec_LogDB_LOGFILE LogDB: Файлы логов
Несмотря на то, что все логи сохраняются в БД, их так же можно писать в файлы.
Для этого каждому логу достаточно указать свойство \b logfile в настройках (см. \ref sec_LogDB_Conf)
\section sec_LogDB_DETAIL LogDB: Технические детали \section sec_LogDB_DETAIL LogDB: Технические детали
Вся реализация построена на "однопоточном" eventloop. В нём происходит, Вся реализация построена на "однопоточном" eventloop. В нём происходит,
...@@ -207,6 +212,7 @@ namespace uniset ...@@ -207,6 +212,7 @@ namespace uniset
void onCheckBuffer( ev::timer& t, int revents ); void onCheckBuffer( ev::timer& t, int revents );
void onActivate( ev::async& watcher, int revents ) ; void onActivate( ev::async& watcher, int revents ) ;
void addLog( Log* log, const std::string& txt ); void addLog( Log* log, const std::string& txt );
void log2File( Log* log, const std::string& txt );
size_t getCountOfRecords( const std::string& logname = "" ); size_t getCountOfRecords( const std::string& logname = "" );
size_t getFirstOfOldRecord( size_t maxnum ); size_t getFirstOfOldRecord( size_t maxnum );
...@@ -270,6 +276,7 @@ namespace uniset ...@@ -270,6 +276,7 @@ namespace uniset
std::string description; std::string description;
std::shared_ptr<DebugStream> dblog; std::shared_ptr<DebugStream> dblog;
std::shared_ptr<DebugStream> logfile;
bool isConnected() const; bool isConnected() const;
......
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<LogDB name="LogDB"> <LogDB name="LogDB">
<logserver name="logserver1" ip="localhost" port="3333" cmd="" description="Лог сервер процесса управления N1"/> <logserver name="logserver1" ip="localhost" port="3333" cmd="" description="Лог сервер процесса управления N1" logfile="/tmp/uniset-test.log"/>
</LogDB> </LogDB>
...@@ -86,9 +86,21 @@ function logdb_test_http_list() ...@@ -86,9 +86,21 @@ function logdb_test_http_list()
logdb_error "test_http_list" "get list must contain 'logserver1'" logdb_error "test_http_list" "get list must contain 'logserver1'"
return 1 return 1
} }
# see config
LOGFILE="/tmp/uniset-test.log"
function logdb_test_logfile()
{
test -f $LOGFILE && return 0
logdb_error "test_logfile" "not found logfile: $LOGFILE"
return 1
}
# ------------------------------------------------------------------------------------------ # ------------------------------------------------------------------------------------------
function logdb_run_all_tests() function logdb_run_all_tests()
{ {
rm -f $LOGFILE
logdb_run_logserver || return 1 logdb_run_logserver || return 1
sleep 3 sleep 3
logdb_run || return 1 logdb_run || return 1
...@@ -98,6 +110,10 @@ function logdb_run_all_tests() ...@@ -98,6 +110,10 @@ function logdb_run_all_tests()
logdb_test_count || RET=1 logdb_test_count || RET=1
logdb_test_http_count || RET=1 logdb_test_http_count || RET=1
logdb_test_http_list || RET=1 logdb_test_http_list || RET=1
logdb_test_logfile || RET 1
# ==== finished ===
rm -f $LOGFILE
} }
create_test_db || exit 1 create_test_db || exit 1
......
...@@ -10,7 +10,7 @@ ...@@ -10,7 +10,7 @@
// but should be adaptable to any project. // but should be adaptable to any project.
// (c) 2002 adapted for UniSet by Lav, GNU LGPL license // (c) 2002 adapted for UniSet by Lav, GNU LGPL license
// Modify for UniSet by pv@eterspft.ru, GNU LGPL license // Modify for UniSet by pv@etersoft.ru, GNU LGPL license
#ifndef DEBUGSTREAM_H #ifndef DEBUGSTREAM_H
#define DEBUGSTREAM_H #define DEBUGSTREAM_H
...@@ -68,7 +68,7 @@ struct Debug ...@@ -68,7 +68,7 @@ struct Debug
If you want to have debug output from time critical code you should If you want to have debug output from time critical code you should
use this construct: use this construct:
if (debug..is_info()) { if (debug.is_info()) {
debug << "...debug output...\n"; debug << "...debug output...\n";
} }
...@@ -160,6 +160,12 @@ class DebugStream : public std::ostream ...@@ -160,6 +160,12 @@ class DebugStream : public std::ostream
logFile(""); logFile("");
} }
// enable print on screen
void enableOnScreen();
// disable print onscreen
void disableOnScreen();
/// Returns true if t is part of the current debug level. /// Returns true if t is part of the current debug level.
inline bool debugging(Debug::type t = Debug::ANY) const noexcept inline bool debugging(Debug::type t = Debug::ANY) const noexcept
{ {
...@@ -297,6 +303,7 @@ class DebugStream : public std::ostream ...@@ -297,6 +303,7 @@ class DebugStream : public std::ostream
std::string logname = { "" }; std::string logname = { "" };
bool isWriteLogFile = { false }; bool isWriteLogFile = { false };
bool onScreen = { true };
}; };
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
#endif #endif
...@@ -134,11 +134,39 @@ void DebugStream::logFile( const std::string& f, bool truncate ) ...@@ -134,11 +134,39 @@ void DebugStream::logFile( const std::string& f, bool truncate )
mode |= truncate ? ios::trunc : ios::app; mode |= truncate ? ios::trunc : ios::app;
internal->fbuf.open(f.c_str(), mode); internal->fbuf.open(f.c_str(), mode);
delete rdbuf(new threebuf(cerr.rdbuf(),
&internal->fbuf, &internal->sbuf)); if( onScreen )
{
delete rdbuf(new threebuf(cerr.rdbuf(),
&internal->fbuf, &internal->sbuf));
}
else
{
// print to cerr disabled
delete rdbuf(new teebuf(&internal->fbuf, &internal->sbuf));
}
} }
else else
delete rdbuf(new teebuf(cerr.rdbuf(), &internal->sbuf)); {
if( onScreen )
delete rdbuf(new teebuf(cerr.rdbuf(), &internal->sbuf));
else
delete rdbuf(&internal->sbuf);
}
}
//--------------------------------------------------------------------------
void DebugStream::enableOnScreen()
{
onScreen = true;
// reopen streams
logFile(fname,false);
}
//--------------------------------------------------------------------------
void DebugStream::disableOnScreen()
{
onScreen = false;
// reopen streams
logFile(fname,false);
} }
//-------------------------------------------------------------------------- //--------------------------------------------------------------------------
std::ostream& DebugStream::debug(Debug::type t) noexcept std::ostream& DebugStream::debug(Debug::type t) noexcept
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment