You need to sign in or sign up before continuing.
Commit 1c9141ee authored by Pavel Vainerman's avatar Pavel Vainerman

(LogServer): сделал предварительную реализацию 'второй части' - 'удалённое управление логами'

parent 1c0113f4
...@@ -5,15 +5,22 @@ ...@@ -5,15 +5,22 @@
#include "UniSetTypes.h" #include "UniSetTypes.h"
#include "Exceptions.h" #include "Exceptions.h"
#include "LogReader.h" #include "LogReader.h"
#include "LogServerTypes.h"
// -------------------------------------------------------------------------- // --------------------------------------------------------------------------
using namespace UniSetTypes; using namespace UniSetTypes;
using namespace std; using namespace std;
// -------------------------------------------------------------------------- // --------------------------------------------------------------------------
static struct option longopts[] = { static struct option longopts[] = {
{ "help", no_argument, 0, 'h' }, { "help", no_argument, 0, 'h' },
{ "verbose", no_argument, 0, 'v' },
{ "iaddr", required_argument, 0, 'a' }, { "iaddr", required_argument, 0, 'a' },
{ "port", required_argument, 0, 'p' }, { "port", required_argument, 0, 'p' },
{ "verbose", no_argument, 0, 'v' }, { "add", required_argument, 0, 'l' },
{ "del", required_argument, 0, 'd' },
{ "set", required_argument, 0, 's' },
{ "off", required_argument, 0, 'o' },
{ "on", required_argument, 0, 'n' },
{ "rotate", required_argument, 0, 'r' },
{ NULL, 0, 0, 0 } { NULL, 0, 0, 0 }
}; };
// -------------------------------------------------------------------------- // --------------------------------------------------------------------------
...@@ -26,17 +33,20 @@ static void print_help() ...@@ -26,17 +33,20 @@ static void print_help()
} }
// -------------------------------------------------------------------------- // --------------------------------------------------------------------------
int main( int argc, char **argv ) int main( int argc, char **argv )
{ {
int optindex = 0; int optindex = 0;
int opt = 0; int opt = 0;
int verb = 0; int verb = 0;
string addr("localhost"); string addr("localhost");
int port = 3333; int port = 3333;
DebugStream dlog; DebugStream dlog;
int cmd = LogServerTypes::cmdNOP;
int data = 0;
string sdata("");
try try
{ {
while( (opt = getopt_long(argc, argv, "hva:p:",longopts,&optindex)) != -1 ) while( (opt = getopt_long(argc, argv, "hva:p:l:d:s:onr",longopts,&optindex)) != -1 )
{ {
switch (opt) switch (opt)
{ {
...@@ -44,6 +54,34 @@ int main( int argc, char **argv ) ...@@ -44,6 +54,34 @@ int main( int argc, char **argv )
print_help(); print_help();
return 0; return 0;
case 'l':
{
cmd = LogServerTypes::cmdAddLevel;
sdata = string(optarg);
}
break;
case 'd':
{
cmd = LogServerTypes::cmdDelLevel;
sdata = string(optarg);
}
break;
case 's':
{
cmd = LogServerTypes::cmdSetLevel;
sdata = string(optarg);
}
break;
case 'o':
cmd = LogServerTypes::cmdOffLogFile;
break;
case 'n':
cmd = LogServerTypes::cmdOnLogFile;
break;
case 'r':
cmd = LogServerTypes::cmdRotate;
break;
case 'a': case 'a':
addr = string(optarg); addr = string(optarg);
break; break;
...@@ -71,7 +109,16 @@ int main( int argc, char **argv ) ...@@ -71,7 +109,16 @@ int main( int argc, char **argv )
} }
LogReader lr; LogReader lr;
lr.readlogs( addr, port, verb );
if( !sdata.empty() )
{
data = (int)Debug::value(sdata);
if( verb )
cout << "SEND COMMAND: '" << (LogServerTypes::Command)cmd << " data='" << sdata << "'" << endl;
}
lr.readlogs( addr, port, (LogServerTypes::Command)cmd, data, verb );
} }
catch( SystemError& err ) catch( SystemError& err )
{ {
......
...@@ -6,6 +6,7 @@ ...@@ -6,6 +6,7 @@
#include <cc++/socket.h> #include <cc++/socket.h>
#include "UTCPStream.h" #include "UTCPStream.h"
#include "DebugStream.h" #include "DebugStream.h"
#include "LogServerTypes.h"
// ------------------------------------------------------------------------- // -------------------------------------------------------------------------
class LogReader class LogReader
{ {
...@@ -14,7 +15,7 @@ class LogReader ...@@ -14,7 +15,7 @@ class LogReader
LogReader(); LogReader();
~LogReader(); ~LogReader();
void readlogs( const std::string& addr, ost::tpport_t port, bool verbose = false ); void readlogs( const std::string& addr, ost::tpport_t port, LogServerTypes::Command c, int data, bool verbose = false );
bool isConnection(); bool isConnection();
......
// -------------------------------------------------------------------------
#ifndef LogServerTypes_H_
#define LogServerTypes_H_
// -------------------------------------------------------------------------
#include <ostream>
// -------------------------------------------------------------------------
namespace LogServerTypes
{
const unsigned int MAGICNUM = 0x20140904;
enum Command
{
cmdNOP, /*!< отсутствие команды */
cmdSetLevel, /*!< установить уровень вывода */
cmdAddLevel, /*!< добавить уровень вывода */
cmdDelLevel, /*!< удалить уровень вывода */
cmdRotate, /*!< пересоздать файл с логами */
cmdOffLogFile, /*!< отключить запись файла логов (если включена) */
cmdOnLogFile /*!< включить запись файла логов (если была отключена) */
// cmdSetLogFile
};
std::ostream& operator<<(std::ostream& os, Command c );
struct lsMessage
{
lsMessage():magic(MAGICNUM),cmd(cmdNOP),data(0){}
unsigned int magic;
Command cmd;
unsigned int data;
// для команды 'cmdSetLogFile'
// static const short MAXLOGFILENAME = 100;
// char logname[MAXLOGFILENAME];
}__attribute__((packed));
std::ostream& operator<<(std::ostream& os, lsMessage& m );
}
// -------------------------------------------------------------------------
#endif // LogServerTypes_H_
// -------------------------------------------------------------------------
...@@ -32,6 +32,7 @@ class LogSession: ...@@ -32,6 +32,7 @@ class LogSession:
LogBuffer lbuf; LogBuffer lbuf;
std::string peername; std::string peername;
std::string caddr; std::string caddr;
DebugStream* log;
timeout_t timeout; timeout_t timeout;
PassiveTimer ptSessionTimeout; PassiveTimer ptSessionTimeout;
......
...@@ -102,14 +102,17 @@ bool LogReader::isConnection() ...@@ -102,14 +102,17 @@ bool LogReader::isConnection()
return tcp && tcp->isConnected(); return tcp && tcp->isConnected();
} }
// ------------------------------------------------------------------------- // -------------------------------------------------------------------------
void LogReader::readlogs( const std::string& _addr, ost::tpport_t _port, bool verbose ) void LogReader::readlogs( const std::string& _addr, ost::tpport_t _port, LogServerTypes::Command cmd, int data, bool verbose )
{ {
timeout_t inTimeout = 10000; timeout_t inTimeout = 10000;
timeout_t outTimeout = 6000;
timeout_t reconDelay = 5000; timeout_t reconDelay = 5000;
char buf[100001]; char buf[100001];
if( verbose ) if( verbose )
rlog.addLevel(Debug::ANY); rlog.addLevel(Debug::ANY);
bool send_ok = false;
while( true ) while( true )
{ {
...@@ -122,7 +125,26 @@ void LogReader::readlogs( const std::string& _addr, ost::tpport_t _port, bool ve ...@@ -122,7 +125,26 @@ void LogReader::readlogs( const std::string& _addr, ost::tpport_t _port, bool ve
msleep(reconDelay); msleep(reconDelay);
continue; continue;
} }
if( !send_ok && cmd != LogServerTypes::cmdNOP )
{
if( tcp->isPending(ost::Socket::pendingOutput,outTimeout) )
{
rlog.info() << "** send command: '" << cmd << "' data='" << data << "'" << endl;
LogServerTypes::lsMessage msg;
msg.cmd = cmd;
msg.data = data;
for( size_t i=0; i<sizeof(msg); i++ )
(*tcp) << ((unsigned char*)(&msg))[i];
tcp->sync();
send_ok = true;
}
else
rlog.warn() << "**** SEND COMMAND ('" << cmd << "' FAILED!" << endl;
}
while( tcp->isPending(ost::Socket::pendingInput,inTimeout) ) while( tcp->isPending(ost::Socket::pendingInput,inTimeout) )
{ {
int n = tcp->peek( buf,sizeof(buf)-1 ); int n = tcp->peek( buf,sizeof(buf)-1 );
...@@ -137,6 +159,7 @@ void LogReader::readlogs( const std::string& _addr, ost::tpport_t _port, bool ve ...@@ -137,6 +159,7 @@ void LogReader::readlogs( const std::string& _addr, ost::tpport_t _port, bool ve
} }
rlog.warn() << "...connection timeout..." << endl; rlog.warn() << "...connection timeout..." << endl;
send_ok = false; // ??!! делать ли?
disconnect(); disconnect();
} }
......
// -------------------------------------------------------------------------
#include "LogServerTypes.h"
// -------------------------------------------------------------------------
using namespace std;
// -------------------------------------------------------------------------
std::ostream& LogServerTypes::operator<<(std::ostream& os, LogServerTypes::Command cmd )
{
switch( cmd )
{
case LogServerTypes::cmdSetLevel:
return os << "cmdSetLevel";
case LogServerTypes::cmdAddLevel:
return os << "cmdAddLevel";
case LogServerTypes::cmdDelLevel:
return os << "cmdDelLevel";
case LogServerTypes::cmdRotate:
return os << "cmdRotate";
case LogServerTypes::cmdOffLogFile:
return os << "cmdOffLogFile";
case LogServerTypes::cmdOnLogFile:
return os << "cmdOnLogFile";
default:
return os << "Unknown";
}
return os;
}
// -------------------------------------------------------------------------
std::ostream& LogServerTypes::operator<<(std::ostream& os, LogServerTypes::lsMessage& m )
{
return os << " magic=" << m.magic << " cmd=" << m.cmd << " data=" << m.data;
}
// -------------------------------------------------------------------------
...@@ -6,6 +6,7 @@ ...@@ -6,6 +6,7 @@
#include <cc++/socket.h> #include <cc++/socket.h>
#include "LogSession.h" #include "LogSession.h"
#include "UniSetTypes.h" #include "UniSetTypes.h"
#include "LogServerTypes.h"
// ------------------------------------------------------------------------- // -------------------------------------------------------------------------
using namespace std; using namespace std;
using namespace UniSetTypes; using namespace UniSetTypes;
...@@ -20,10 +21,11 @@ LogSession::~LogSession() ...@@ -20,10 +21,11 @@ LogSession::~LogSession()
} }
} }
// ------------------------------------------------------------------------- // -------------------------------------------------------------------------
LogSession::LogSession( ost::TCPSocket &server, DebugStream* log, timeout_t msec ): LogSession::LogSession( ost::TCPSocket &server, DebugStream* _log, timeout_t msec ):
TCPSession(server), TCPSession(server),
peername(""), peername(""),
caddr(""), caddr(""),
log(_log),
timeout(msec), timeout(msec),
cancelled(false) cancelled(false)
{ {
...@@ -61,19 +63,78 @@ void LogSession::run() ...@@ -61,19 +63,78 @@ void LogSession::run()
timeout_t inTimeout = 2000; timeout_t inTimeout = 2000;
timeout_t outTimeout = 2000; timeout_t outTimeout = 2000;
string oldLogFile( log->getLogFile() );
// Команды могут посылаться только в начале сессии..
if( isPending(Socket::pendingInput, inTimeout) )
{
LogServerTypes::lsMessage msg;
// проверяем канал..(если данных нет, значит "клиент отвалился"...
if( peek( (void*)(&msg),sizeof(msg)) > 0 )
{
ssize_t ret = readData( &msg,sizeof(msg) );
if( ret!=sizeof(msg) || msg.magic!=LogServerTypes::MAGICNUM )
slog.warn() << peername << "(run): BAD MESSAGE..." << endl;
else
{
slog.info() << peername << "(run): receive command: '" << msg.cmd << "'" << endl;
// Обработка команд..
// \warning Работа с логом ведётся без mutex-а, хотя он разделяется отдельными потоками
switch( msg.cmd )
{
case LogServerTypes::cmdSetLevel:
log->level( (Debug::type)msg.data );
break;
case LogServerTypes::cmdAddLevel:
log->addLevel((Debug::type)msg.data );
break;
case LogServerTypes::cmdDelLevel:
log->delLevel( (Debug::type)msg.data );
break;
case LogServerTypes::cmdRotate:
{
string lfile( log->getLogFile() );
if( !lfile.empty() )
log->logFile(lfile);
}
break;
case LogServerTypes::cmdOffLogFile:
{
string lfile( log->getLogFile() );
if( !lfile.empty() )
log->logFile("");
}
break;
case LogServerTypes::cmdOnLogFile:
{
if( !oldLogFile.empty() && oldLogFile != log->getLogFile() )
log->logFile(oldLogFile);
}
break;
default:
slog.warn() << peername << "(run): Unknown command '" << msg.cmd << "'" << endl;
break;
}
}
}
}
cancelled = false; cancelled = false;
while( !cancelled && !ptSessionTimeout.checkTime() ) while( !cancelled && !ptSessionTimeout.checkTime() )
{ {
if( isPending(Socket::pendingInput, inTimeout) ) // проверка только ради проверки "целостности" соединения
{ if( isPending(Socket::pendingInput, 10) )
char buf[100]; {
char buf[10];
// проверяем канал..(если данных нет, значит "клиент отвалился"... // проверяем канал..(если данных нет, значит "клиент отвалился"...
if( peek(buf,sizeof(buf)) <=0 ) if( peek(buf,sizeof(buf)) <=0 )
break; break;
ptSessionTimeout.reset();
slog.warn() << peername << "(run): receive command.." << endl;
// Обработка команд..
} }
if( isPending(Socket::pendingOutput, outTimeout) ) if( isPending(Socket::pendingOutput, outTimeout) )
...@@ -83,12 +144,14 @@ void LogSession::run() ...@@ -83,12 +144,14 @@ void LogSession::run()
uniset_rwmutex_wrlock l(mLBuf); uniset_rwmutex_wrlock l(mLBuf);
if( !lbuf.empty() ) if( !lbuf.empty() )
slog.info() << peername << "(run): send messages.." << endl;
while( !lbuf.empty() )
{ {
*tcp() << lbuf.front(); slog.info() << peername << "(run): send messages.." << endl;
lbuf.pop_front(); while( !lbuf.empty() )
{
*tcp() << lbuf.front();
lbuf.pop_front();
}
tcp()->sync();
} }
} }
} }
......
...@@ -4,6 +4,5 @@ ...@@ -4,6 +4,5 @@
noinst_LTLIBRARIES = libLogServer.la noinst_LTLIBRARIES = libLogServer.la
libLogServer_la_CPPFLAGS = $(SIGC_CFLAGS) $(COMCPP_CFLAGS) libLogServer_la_CPPFLAGS = $(SIGC_CFLAGS) $(COMCPP_CFLAGS)
#libLogServer_la_LIBADD = $(top_builddir)/src/Communications/TCP/libTCP.la $(SIGC_LIBS) $(COMCPP_LIBS)
libLogServer_la_LIBADD = $(SIGC_LIBS) $(COMCPP_LIBS) libLogServer_la_LIBADD = $(SIGC_LIBS) $(COMCPP_LIBS)
libLogServer_la_SOURCES = LogServer.cc LogSession.cc LogReader.cc libLogServer_la_SOURCES = LogServerTypes.cc LogServer.cc LogSession.cc LogReader.cc
...@@ -375,9 +375,15 @@ void DebugStream::logFile( const std::string& f ) ...@@ -375,9 +375,15 @@ void DebugStream::logFile( const std::string& f )
} else { } else {
internal = new debugstream_internal; internal = new debugstream_internal;
} }
internal->fbuf.open(f.c_str(), ios::out|ios::app);
delete rdbuf(new threebuf(cerr.rdbuf(), if( !f.empty() )
{
internal->fbuf.open(f.c_str(), ios::out|ios::app);
delete rdbuf(new threebuf(cerr.rdbuf(),
&internal->fbuf,&internal_sbuf->sbuf)); &internal->fbuf,&internal_sbuf->sbuf));
}
else
delete rdbuf(new teebuf(cerr.rdbuf(),&internal_sbuf->sbuf));
} }
//-------------------------------------------------------------------------- //--------------------------------------------------------------------------
std::ostream & DebugStream::debug(Debug::type t) std::ostream & DebugStream::debug(Debug::type t)
......
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