Commit 13ac8507 authored by Pavel Vainerman's avatar Pavel Vainerman

(LogDB): ушёл от использования getopt при разборе команд

(т.к. оставил только три команды set,add,del.
parent 00eb5a61
......@@ -62,6 +62,7 @@ LogDB::LogDB( const string& name , const string& prefix ):
checkBufferTimer.set<LogDB, &LogDB::onCheckBuffer>(this);
UniXML::iterator sit(cnode);
if( !sit.goChildren() )
{
ostringstream err;
......@@ -70,7 +71,7 @@ LogDB::LogDB( const string& name , const string& prefix ):
throw uniset::SystemError(err.str());
}
for( ;sit.getCurrent(); sit++ )
for( ; sit.getCurrent(); sit++ )
{
auto l = make_shared<Log>();
......@@ -103,15 +104,15 @@ LogDB::LogDB( const string& name , const string& prefix ):
throw uniset::SystemError(err.str());
}
// if( l->cmd.empty() )
// {
// ostringstream err;
// err << name << "(init): Unknown 'cmd' for '" << l->name << "'..";
// dbcrit << err.str() << endl;
// throw uniset::SystemError(err.str());
// }
// if( l->cmd.empty() )
// {
// ostringstream err;
// err << name << "(init): Unknown 'cmd' for '" << l->name << "'..";
// dbcrit << err.str() << endl;
// throw uniset::SystemError(err.str());
// }
// l->tcp = make_shared<UTCPStream>();
// l->tcp = make_shared<UTCPStream>();
l->dblog = dblog;
l->signal_on_read().connect(sigc::mem_fun(this, &LogDB::addLog));
......@@ -128,6 +129,7 @@ LogDB::LogDB( const string& name , const string& prefix ):
std::string dbfile = conf->getArgParam("--" + prefix + "-dbfile", it.getProp("dbfile"));
if( dbfile.empty() )
{
ostringstream err;
......@@ -137,12 +139,13 @@ LogDB::LogDB( const string& name , const string& prefix ):
}
db = unisetstd::make_unique<SQLiteInterface>();
if( !db->connect(dbfile, false) )
{
ostringstream err;
err << myname
<< "(init): DB connection error: "
<< db->error();
<< "(init): DB connection error: "
<< db->error();
dbcrit << err.str() << endl;
throw uniset::SystemError(err.str());
}
......@@ -240,7 +243,7 @@ void LogDB::onTimer( ev::timer& t, int revents )
}
// проверяем соединения..
for( const auto& s: logservers )
for( const auto& s : logservers )
{
if( !s->isConnected() )
{
......@@ -272,7 +275,7 @@ bool LogDB::Log::connect() noexcept
if( tcp && tcp->isConnected() )
return true;
// dbinfo << name << "(connect): connect " << ip << ":" << port << "..." << endl;
// dbinfo << name << "(connect): connect " << ip << ":" << port << "..." << endl;
if( peername.empty() )
peername = ip + ":" + std::to_string(port);
......@@ -281,8 +284,8 @@ bool LogDB::Log::connect() noexcept
{
tcp = make_shared<UTCPStream>();
tcp->create(ip, port);
// tcp->setReceiveTimeout( UniSetTimer::millisecToPoco(inTimeout) );
// tcp->setSendTimeout( UniSetTimer::millisecToPoco(outTimeout) );
// tcp->setReceiveTimeout( UniSetTimer::millisecToPoco(inTimeout) );
// tcp->setSendTimeout( UniSetTimer::millisecToPoco(outTimeout) );
tcp->setKeepAlive(true);
tcp->setBlocking(false);
dbinfo << name << "(connect): connect OK to " << ip << ":" << port << endl;
......@@ -304,7 +307,7 @@ bool LogDB::Log::connect() noexcept
{
std::exception_ptr p = std::current_exception();
dbwarn << name << "(connect): connection " << peername << " error: "
<< (p ? p.__cxa_exception_type()->name() : "null") << endl;
<< (p ? p.__cxa_exception_type()->name() : "null") << endl;
}
tcp->disconnect();
......@@ -327,9 +330,10 @@ void LogDB::Log::ioprepare( ev::dynamic_loop& loop )
//! \todo Пока закрываем глаза на не оптимальность, того, что парсим строку каждый раз
auto cmdlist = LogServerTypes::getCommands(cmd);
if( !cmdlist.empty() )
{
for( const auto& msg: cmdlist )
for( const auto& msg : cmdlist )
wbuf.emplace(new UTCPCore::Buffer((unsigned char*)&msg, sizeof(msg)));
io.set(ev::WRITE);
......@@ -363,21 +367,22 @@ void LogDB::Log::read( ev::io& watcher )
int n = tcp->available();
n = std::min(n,bufsize);
n = std::min(n, bufsize);
if( n > 0 )
{
tcp->receiveBytes(buf, n);
// нарезаем на строки
for( size_t i=0; i<n; i++ )
for( size_t i = 0; i < n; i++ )
{
if( buf[i] != '\n' )
text += buf[i];
else
{
sigRead.emit(this,text);
sigRead.emit(this, text);
text = "";
if( text.capacity() < reservsize )
text.reserve(reservsize);
}
......@@ -386,13 +391,16 @@ void LogDB::Log::read( ev::io& watcher )
else if( n == 0 )
{
dbinfo << name << ": " << ip << ":" << port << " connection is closed.." << endl;
if( !text.empty() )
{
sigRead.emit(this,text);
sigRead.emit(this, text);
text = "";
if( text.capacity() < reservsize )
text.reserve(reservsize);
}
close();
}
}
......@@ -400,6 +408,7 @@ void LogDB::Log::read( ev::io& watcher )
void LogDB::Log::write( ev::io& io )
{
UTCPCore::Buffer* buffer = 0;
if( wbuf.empty() )
{
io.set(EV_READ);
......
......@@ -115,37 +115,37 @@ namespace uniset
class Log
{
public:
std::string name;
std::string ip;
int port = { 0 };
std::string cmd;
std::string peername;
std::string name;
std::string ip;
int port = { 0 };
std::string cmd;
std::string peername;
std::shared_ptr<DebugStream> dblog;
std::shared_ptr<DebugStream> dblog;
bool connect() noexcept;
bool isConnected() const;
void ioprepare( ev::dynamic_loop& loop );
void event( ev::io& watcher, int revents );
void read( ev::io& watcher);
void write(ev::io& io );
void close();
bool connect() noexcept;
bool isConnected() const;
void ioprepare( ev::dynamic_loop& loop );
void event( ev::io& watcher, int revents );
void read( ev::io& watcher);
void write( ev::io& io );
void close();
typedef sigc::signal<void, Log*, const std::string&> ReadSignal;
ReadSignal signal_on_read();
typedef sigc::signal<void, Log*, const std::string&> ReadSignal;
ReadSignal signal_on_read();
private:
ReadSignal sigRead;
ev::io io;
std::shared_ptr<UTCPStream> tcp;
static const int bufsize = { 10001 };
char buf[bufsize];
ReadSignal sigRead;
ev::io io;
std::shared_ptr<UTCPStream> tcp;
static const int bufsize = { 10001 };
char buf[bufsize];
static const size_t reservsize = { 1000 };
std::string text;
static const size_t reservsize = { 1000 };
std::string text;
// буфер для посылаемых данных (write buffer)
std::queue<UTCPCore::Buffer*> wbuf;
// буфер для посылаемых данных (write buffer)
std::queue<UTCPCore::Buffer*> wbuf;
};
std::vector< std::shared_ptr<Log> > logservers;
......
......@@ -84,11 +84,6 @@ namespace uniset
* [-a | --add] info,warn,crit,... [logfilter] - Add log levels.
* [-d | --del] info,warn,crit,... [logfilter] - Delete log levels.
* [-s | --set] info,warn,crit,... [logfilter] - Set log levels.
* [-o | --off] [logfilter] - Off the write log file (if enabled).
* [-e | --on] [logfilter] - On(enable) the write log file (if before disabled).
* [-r | --rotate] [logfilter] - rotate log file.
* [-u | --save-loglevels] [logfilter] - save log levels (disable restore after disconnected).
* [-y | --restore-loglevels] [logfilter] - restore default log levels.
*
* 'logfilter' - regexp for name of log. Default: ALL logs
*/
......
......@@ -14,7 +14,6 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
// -------------------------------------------------------------------------
#include <getopt.h> // не хорошо завязыватся на getopt.. но пока так удобнее
#include "UniSetTypes.h"
#include "LogServerTypes.h"
#include "Debug.h"
......@@ -84,183 +83,55 @@ namespace uniset
logname[s] = '\0';
}
// -------------------------------------------------------------------------
static struct option longopts[] =
static const std::string checkArg( size_t i, const std::vector<std::string>& v )
{
{ "add", required_argument, 0, 'a' },
{ "del", required_argument, 0, 'd' },
{ "set", required_argument, 0, 's' },
{ "off", required_argument, 0, 'o' },
{ "on", required_argument, 0, 'e' },
{ "save-loglevels", required_argument, 0, 'u' },
{ "restore-loglevels", required_argument, 0, 'y' },
{ "rotate", optional_argument, 0, 'r' },
{ "logfilter", required_argument, 0, 'n' },
{ "timeout", required_argument, 0, 't' },
{ "reconnect-delay", required_argument, 0, 'x' },
{ NULL, 0, 0, 0 }
};
// --------------------------------------------------------------------------
static const char* checkArg( int i, int argc, const char* argv[] )
{
if( i < argc && (argv[i])[0] != '-' )
return argv[i];
if( i < v.size() && (v[i])[0] != '-' )
return v[i];
return 0;
return "";
}
// --------------------------------------------------------------------------
std::vector<LogServerTypes::lsMessage> LogServerTypes::getCommands( const std::string& cmd )
{
// формируем argc, argv и проходим getopt-ом
// пока это самый простой способ..
vector<lsMessage> vcmd;
auto v = uniset::explode_str(cmd,' ');
const size_t argc = v.size()+1;
const char** argv = new const char*[argc];
argv[0] = " ";
for( size_t i=1; i<argc; i++ )
argv[i] = v[i-1].c_str(); // use strdup?
int optindex = 0;
int opt = 0;
vector<lsMessage> vcmd;
if( v.empty() )
return vcmd;
while(1)
for( size_t i=0; i < v.size(); i++ )
{
opt = getopt_long(argc, (char**)argv, "la:d:s:n:eorx:t:uby:", longopts, &optindex);
if( opt == -1 )
break;
switch (opt)
{
case 'a':
{
LogServerTypes::Command cmd = LogServerTypes::cmdAddLevel;
std::string filter("");
std::string d = string(optarg);
const char* arg2 = checkArg(optind, argc, argv);
if( arg2 )
filter = string(arg2);
vcmd.emplace_back(cmd, (int)Debug::value(d), filter);
}
break;
case 'd':
{
LogServerTypes::Command cmd = LogServerTypes::cmdDelLevel;
std::string filter("");
std::string d = string(optarg);
const char* arg2 = checkArg(optind, argc, argv);
if( arg2 )
filter = string(arg2);
vcmd.emplace_back(cmd, (int)Debug::value(d), filter );
}
break;
case 's':
{
LogServerTypes::Command cmd = LogServerTypes::cmdSetLevel;
std::string filter("");
std::string d = string(optarg);
const char* arg2 = checkArg(optind, argc, argv);
if( arg2 )
filter = string(arg2);
vcmd.emplace_back(cmd, (int)Debug::value(d), filter );
}
break;
case 'l':
{
std::string filter("");
const char* arg2 = checkArg(optind, argc, argv);
if( arg2 )
filter = string(arg2);
auto c = v[i];
vcmd.emplace_back(LogServerTypes::cmdList, 0, filter);
}
break;
string arg1 = checkArg(i+1, v);
if( arg1.empty() )
continue;
case 'o':
{
LogServerTypes::Command cmd = LogServerTypes::cmdOffLogFile;
std::string filter("");
const char* arg2 = checkArg(optind, argc, argv);
i++;
if( arg2 )
filter = string(arg2);
std::string filter = checkArg(i+2,v);
if( !filter.empty() )
i++;
vcmd.emplace_back(cmd, 0, filter);
}
break;
case 'u': // --save-loglevels
{
LogServerTypes::Command cmd = LogServerTypes::cmdSaveLogLevel;
std::string filter("");
const char* arg2 = checkArg(optind, argc, argv);
if( arg2 )
filter = string(arg2);
vcmd.emplace_back(cmd, 0, filter);
}
break;
case 'y': // --restore-loglevels
{
LogServerTypes::Command cmd = LogServerTypes::cmdRestoreLogLevel;
std::string filter("");
const char* arg2 = checkArg(optind, argc, argv);
if( arg2 )
filter = string(arg2);
vcmd.emplace_back(cmd, 0, filter);
}
break;
case 'e':
{
LogServerTypes::Command cmd = LogServerTypes::cmdOnLogFile;
std::string filter("");
const char* arg2 = checkArg(optind, argc, argv);
if( arg2 )
filter = string(arg2);
vcmd.emplace_back(cmd, 0, filter);
}
break;
case 'r':
{
LogServerTypes::Command cmd = LogServerTypes::cmdRotate;
std::string filter("");
const char* arg2 = checkArg(optind, argc, argv);
if( arg2 )
filter = string(arg2);
vcmd.emplace_back(cmd, 0, filter);
}
break;
case '?':
default:
break;
if( c == "-s" || c == "--set" )
{
LogServerTypes::Command cmd = LogServerTypes::cmdSetLevel;
vcmd.emplace_back(cmd, (int)Debug::value(arg1), filter);
}
else if( c == "-a" || c == "--add" )
{
LogServerTypes::Command cmd = LogServerTypes::cmdAddLevel;
vcmd.emplace_back(cmd, (int)Debug::value(arg1), filter);
}
else if( c == "-d" || c == "--del" )
{
LogServerTypes::Command cmd = LogServerTypes::cmdDelLevel;
vcmd.emplace_back(cmd, (int)Debug::value(arg1), filter);
}
}
delete[] argv;
return vcmd;
}
// -------------------------------------------------------------------------
......
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