Commit 807617b0 authored by Pavel Vainerman's avatar Pavel Vainerman

Merge branch 'log-monitor'

parents f9fa80af 41cba1cc
......@@ -3,7 +3,7 @@
############################################################################
SUBDIRS = scripts Admin NullController SViewer-text \
SMonit MBTester codegen SImitator
SMonit MBTester codegen SImitator ULog
bin_PROGRAMS = @PACKAGE@-log @PACKAGE@-logserver-wrap
noinst_PROGRAMS = @PACKAGE@-test-logserver @PACKAGE@-log-stdin
@PACKAGE@_test_logserver_SOURCES = logserver.cc
@PACKAGE@_test_logserver_LDADD = $(top_builddir)/lib/libUniSet2.la $(COMCPP_LIBS)
@PACKAGE@_test_logserver_CPPFLAGS = $(COMCPP_CFLAGS)
@PACKAGE@_log_SOURCES = log.cc
@PACKAGE@_log_LDADD = $(top_builddir)/lib/libUniSet2.la $(COMCPP_LIBS)
@PACKAGE@_log_CPPFLAGS = $(COMCPP_CFLAGS)
@PACKAGE@_log_stdin_SOURCES = log-stdin.cc
@PACKAGE@_log_stdin_LDADD = $(top_builddir)/lib/libUniSet2.la $(COMCPP_LIBS)
@PACKAGE@_log_stdin_CPPFLAGS = $(COMCPP_CFLAGS)
@PACKAGE@_logserver_wrap_SOURCES = log-wrap.cc
@PACKAGE@_logserver_wrap_LDADD = $(top_builddir)/lib/libUniSet2.la $(COMCPP_LIBS)
@PACKAGE@_logserver_wrap_CPPFLAGS = $(COMCPP_CFLAGS)
// --------------------------------------------------------------------------
#include <getopt.h>
#include <iostream>
#include <string>
#include "DebugStream.h"
#include "LogServer.h"
#include "Exceptions.h"
// --------------------------------------------------------------------------
using namespace UniSetTypes;
using namespace std;
// -------------------------------------------------------------------------
static struct option longopts[] = {
{ "help", no_argument, 0, 'h' },
{ "iaddr", required_argument, 0, 'i' },
{ "port", required_argument, 0, 'p' },
{ "verbose", no_argument, 0, 'v' },
{ NULL, 0, 0, 0 }
};
// --------------------------------------------------------------------------
static void print_help()
{
printf("-h - this message\n");
printf("-v - Print all messages to stdout\n");
printf("-i addr - LogServer ip or hostname. Default: localhost.\n");
printf("-p port - LogServer port. Default: 3333.\n");
}
// --------------------------------------------------------------------------
int main( int argc, char* argv[], char* envp[] )
{
int optindex = 0;
int opt = 0;
int verb = 0;
string addr("localhost");
int port = 3333;
try
{
while( (opt = getopt_long(argc, argv, "hvi:p:",longopts,&optindex)) != -1 )
{
switch (opt)
{
case 'h':
print_help();
return 0;
case 'i':
addr = string(optarg);
break;
case 'p':
port = atoi(optarg);
break;
case 'v':
verb = 1;
break;
case '?':
default:
printf("? argumnet\n");
return 0;
}
}
if( verb )
cout << "(init): listen " << addr << ":" << port << endl;
DebugStream log;
LogServer ls(log);
ls.run(addr,port,true);
char buf[10000];
while( true )
{
size_t r = read(fileno(stdin), buf, sizeof(buf)-1);
if( r > 0 )
{
buf[r] = '\0';
log << buf;
}
}
}
catch( SystemError& err )
{
cerr << "(log-stdin): " << err << endl;
return 1;
}
catch( Exception& ex )
{
cerr << "(log-stdin): " << ex << endl;
return 1;
}
catch(...)
{
cerr << "(log-stdin): catch(...)" << endl;
return 1;
}
return 0;
}
// --------------------------------------------------------------------------
// --------------------------------------------------------------------------
#include <string>
#include "DebugStream.h"
#include "UniSetTypes.h"
#include "LogServer.h"
#include "LogServerTypes.h"
#include "Exceptions.h"
#include <sys/wait.h>
#include <cstdio>
#include <cstdlib>
#include <unistd.h>
#include <cstring>
// --------------------------------------------------------------------------
using namespace UniSetTypes;
using namespace std;
// -------------------------------------------------------------------------
static void print_help()
{
printf("\n");
printf("Usage: uniset2-logserver-wrap listen-addr listen-port PROGRAMM ARGS..\n");
printf("\n");
}
// --------------------------------------------------------------------------
int main( int argc, char* argv[], char* envp[] )
{
if( argc < 4 )
{
print_help();
return 1;
}
string addr(argv[1]);
int port = atoi(argv[2]);
int pid;
int cp[2]; /* Child to parent pipe */
if( pipe(cp) < 0)
{
perror("Can't make pipe");
exit(1);
}
try
{
switch( pid = fork() )
{
case -1:
{
perror("Can't fork");
exit(1);
}
case 0:
{
/* Child. */
close(cp[0]);
close( fileno(stdout) );
dup2(cp[1],fileno(stdout));
close( fileno(stderr) );
dup2(fileno(stdout),fileno(stderr));
execvpe(argv[3], argv + 3, envp);
perror("No exec");
kill(getppid(), SIGQUIT);
exit(1);
}
break;
default:
{
/* Parent. */
close(cp[1]);
DebugStream zlog;
zlog.addLevel(Debug::ANY);
LogServer ls(zlog);
cout << "wrap: server " << addr << ":" << port << endl;
ls.run( addr, port, true );
char buf[5000];
while( true )
{
ssize_t r = read(cp[0], &buf, sizeof(buf)-1 );
if( r > 0 )
{
buf[r] = '\0';
zlog << buf;
}
}
exit(0);
}
break;
}
}
catch( SystemError& err )
{
cerr << "(logserver-wrap): " << err << endl;
return 1;
}
catch( Exception& ex )
{
cerr << "(logserver-wrap): " << ex << endl;
return 1;
}
catch(...)
{
cerr << "(logserver-wrap): catch(...)" << endl;
return 1;
}
return 0;
}
// --------------------------------------------------------------------------
// --------------------------------------------------------------------------
#include <string>
#include <getopt.h>
#include "Debug.h"
#include "UniSetTypes.h"
#include "Exceptions.h"
#include "LogReader.h"
#include "LogServerTypes.h"
// --------------------------------------------------------------------------
using namespace UniSetTypes;
using namespace std;
// --------------------------------------------------------------------------
static struct option longopts[] = {
{ "help", no_argument, 0, 'h' },
{ "verbose", no_argument, 0, 'v' },
{ "iaddr", required_argument, 0, 'i' },
{ "port", required_argument, 0, 'p' },
{ "add", required_argument, 0, 'a' },
{ "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' },
{ "logname", required_argument, 0, 'l' },
{ "command-only", no_argument, 0, 'b' },
{ NULL, 0, 0, 0 }
};
// --------------------------------------------------------------------------
static void print_help()
{
printf("-h, --help - this message\n");
printf("-v, --verbose - Print all messages to stdout\n");
printf("[-i|--iaddr] addr - LogServer ip or hostname.\n");
printf("[-p|--port] port - LogServer port.\n");
printf("[-l|--logname] name - Send command only for 'logname'.\n");
printf("[-b|--command-only] - Send command and break. (No read logs).\n");
printf("\n");
printf("Commands:\n");
printf("[--add | -a] info,warn,crit,... - Add log levels.\n");
printf("[--del | -d] info,warn,crit,... - Delete log levels.\n");
printf("[--set | -s] info,wanr,crit,... - Set log levels.\n");
printf("--off, -o - Off the write log file (if enabled).\n");
printf("--on, -n - On the write log file (if before disabled).\n");
printf("--rotate, -r - rotate log file.\n");
}
// --------------------------------------------------------------------------
int main( int argc, char **argv )
{
int optindex = 0;
int opt = 0;
int verb = 0;
string addr("localhost");
int port = 3333;
DebugStream dlog;
int cmd = LogServerTypes::cmdNOP;
int data = 0;
string sdata("");
int cmdonly = 0;
string logname("");
try
{
while( (opt = getopt_long(argc, argv, "hva:p:i:d:s:l:onrb",longopts,&optindex)) != -1 )
{
switch (opt)
{
case 'h':
print_help();
return 0;
case 'a':
{
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 'i':
addr = string(optarg);
break;
case 'l':
logname = string(optarg);
break;
case 'b':
cmdonly = 1;
break;
case 'p':
port = uni_atoi(optarg);
break;
case 'v':
verb = 1;
break;
case '?':
default:
printf("? argumnet\n");
return 0;
}
}
if( verb )
{
cout << "(init): read from " << addr << ":" << port << endl;
dlog.addLevel( Debug::type(Debug::CRIT | Debug::WARN | Debug::INFO) );
}
LogReader lr;
lr.setCommandOnlyMode(cmdonly);
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, logname, verb );
}
catch( SystemError& err )
{
cerr << "(log): " << err << endl;
}
catch( Exception& ex )
{
cerr << "(log): " << ex << endl;
}
catch(...)
{
cerr << "(log): catch(...)" << endl;
}
return 0;
}
// --------------------------------------------------------------------------
// --------------------------------------------------------------------------
#include <string>
#include <getopt.h>
#include "Debug.h"
#include "UniSetTypes.h"
#include "Exceptions.h"
#include "LogServer.h"
#include "LogAgregator.h"
// --------------------------------------------------------------------------
using namespace UniSetTypes;
using namespace std;
// --------------------------------------------------------------------------
static struct option longopts[] = {
{ "help", no_argument, 0, 'h' },
{ "iaddr", required_argument, 0, 'i' },
{ "port", required_argument, 0, 'p' },
{ "verbose", no_argument, 0, 'v' },
{ "delay", required_argument, 0, 'd' },
{ NULL, 0, 0, 0 }
};
// --------------------------------------------------------------------------
static void print_help()
{
printf("-h|--help - this message\n");
// printf("[-t|--timeout] msec - Timeout. Default: 2000.\n");
printf("[-v|--verbose] - Print all messages to stdout\n");
printf("[-i|--iaddr] addr - Inet address for listen connections.\n");
printf("[-p|--port] port - Bind port.\n");
printf("[-d|--delay] msec - Delay for generate message. Default 5000.\n");
}
// --------------------------------------------------------------------------
int main( int argc, char **argv )
{
int optindex = 0;
int opt = 0;
int verb = 0;
string addr("localhost");
int port = 3333;
int tout = 2000;
timeout_t delay = 5000;
try
{
while( (opt = getopt_long(argc, argv, "hvi:p:d:",longopts,&optindex)) != -1 )
{
switch (opt)
{
case 'h':
print_help();
return 0;
case 'i':
addr = string(optarg);
break;
case 'p':
port = uni_atoi(optarg);
break;
case 'd':
delay = uni_atoi(optarg);
break;
case 'v':
verb = 1;
break;
case '?':
default:
printf("? argumnet\n");
return 0;
}
}
if( verb )
{
cout << "(init): listen " << addr << ":" << port
// << " timeout=" << tout << " msec "
<< endl;
// dlog.addLevel( Debug::type(Debug::CRIT | Debug::WARN | Debug::INFO) );
}
DebugStream dlog;
dlog.setLogName("dlog");
DebugStream dlog2;
dlog2.setLogName("dlog2");
LogAgregator la;
la.add(dlog);
la.add(dlog2);
LogServer ls(la);
// LogServer ls(cout);
dlog.addLevel(Debug::ANY);
dlog2.addLevel(Debug::ANY);
ls.run( addr, port, true );
unsigned int i=0;
while( true )
{
dlog << "[" << ++i << "] Test message for log" << endl;
dlog.info() << ": dlog : INFO message" << endl;
dlog.warn() << ": dlog : WARN message" << endl;
dlog.crit() << ": dlog : CRIT message" << endl;
dlog2.info() << ": dlog2: INFO message" << endl;
dlog2.warn() << ": dlog2: WARN message" << endl;
dlog2.crit() << ": dlog2: CRIT message" << endl;
msleep(delay);
}
}
catch( SystemError& err )
{
cerr << "(logserver): " << err << endl;
}
catch( Exception& ex )
{
cerr << "(logserver): " << ex << endl;
}
catch(...)
{
cerr << "(logserver): catch(...)" << endl;
}
return 0;
}
// --------------------------------------------------------------------------
#!/bin/sh
for i in `seq 1 60`; do
echo "MSG$i"
sleep 1
done
\ No newline at end of file
......@@ -319,7 +319,7 @@ void <xsl:value-of select="$CLASSNAME"/>_SK::sysCommand( const SystemMessage* _s
string fname( mylog.getLogFile() );
if( !fname.empty() )
{
mylog.logFile(fname.c_str());
mylog.logFile(fname.c_str(),true);
mylog &lt;&lt; myname &lt;&lt; "(sysCommand): ***************** mylog LOG ROTATE *****************" &lt;&lt; endl;
}
}
......
......@@ -14,7 +14,7 @@
<AutoStartUpTime name="1"/>
<DumpStateTime name="10"/>
<SleepTickMS name="500"/>
<UniSetDebug levels="crit,warn" name="ulog"/>
<UniSetDebug levels="" name="ulog"/>
<ConfDir name="./"/>
<DataDir name="./"/>
<BinDir name="./"/>
......@@ -32,6 +32,8 @@
</Services>
</UniSet>
<dlog name="dlog"/>
<LogServer name="smplus" port="3333" host="localhost" />
<settings>
<TestProc name="TestProc1"
on_s="Input1_S"
......
......@@ -186,8 +186,8 @@ AC_SUBST(UNISET_EXT_LIBS)
# export
LDFLAGS="${OMNI_LIBS} ${XML_LIBS}"
CXXFLAGS="-pedantic -Wall -funsigned-char -std=c++11 -g -D_GNU_SOURCE ${OMNI_CFLAGS} ${XML_CFLAGS} -I\$(top_builddir)/include"
LDFLAGS="${OMNI_LIBS} ${XML_LIBS} ${SIGC_LIBS}"
CXXFLAGS="-pedantic -Wall -funsigned-char -std=c++11 -g -D_GNU_SOURCE ${OMNI_CFLAGS} ${XML_CFLAGS} ${SIGC_CFLAGS} -I\$(top_builddir)/include"
AC_SUBST(LDFLAGS)
AC_SUBST(CXXFLAGS)
......@@ -221,12 +221,14 @@ AC_CONFIG_FILES([Makefile
IDL/Processes/Makefile
src/Communications/Makefile
src/Communications/Modbus/Makefile
src/Communications/TCP/Makefile
src/Interfaces/Makefile
src/ObjectRepository/Makefile
src/Processes/Makefile
src/Services/Makefile
src/Timers/Makefile
src/Various/Makefile
src/Log/Makefile
src/Makefile
include/Makefile
include/modbus/Makefile
......@@ -246,6 +248,7 @@ AC_CONFIG_FILES([Makefile
Utilities/codegen/Makefile
Utilities/codegen/uniset2-codegen
Utilities/codegen/tests/Makefile
Utilities/ULog/Makefile
extensions/Makefile
extensions/libUniSet2Extensions.pc
extensions/lib/Makefile
......
......@@ -1226,7 +1226,7 @@ void IOControl::sysCommand( const SystemMessage* sm )
string fname( ulog.getLogFile() );
if( !fname.empty() )
{
ulog.logFile(fname);
ulog.logFile(fname,true);
ulog << myname << "(sysCommand): ***************** ulog LOG ROTATE *****************" << endl;
}
......@@ -1234,7 +1234,7 @@ void IOControl::sysCommand( const SystemMessage* sm )
fname = dlog.getLogFile();
if( !fname.empty() )
{
dlog.logFile(fname);
dlog.logFile(fname,true);
dlog << myname << "(sysCommand): ***************** GGDEB LOG ROTATE *****************" << endl;
}
}
......
......@@ -148,7 +148,7 @@ void PassiveLProcessor::sysCommand( const UniSetTypes::SystemMessage *sm )
string fname (ulog.getLogFile() );
if( !fname.empty() )
{
ulog.logFile(fname);
ulog.logFile(fname,true);
ulog << myname << "(sysCommand): ***************** ulog LOG ROTATE *****************" << std::endl;
}
......@@ -156,7 +156,7 @@ void PassiveLProcessor::sysCommand( const UniSetTypes::SystemMessage *sm )
fname = dlog.getLogFile();
if( !fname.empty() )
{
dlog.logFile(fname);
dlog.logFile(fname,true);
dlog << myname << "(sysCommand): ***************** dlog LOG ROTATE *****************" << std::endl;
}
}
......
......@@ -165,13 +165,19 @@ MBExchange::~MBExchange()
{
if( it1->second->rtu )
{
delete it1->second->rtu;
it1->second->rtu = 0;
try {
delete it1->second->rtu;
it1->second->rtu = 0;
}catch(...){}
}
RTUDevice* d(it1->second);
for( auto it=d->regmap.begin(); it!=d->regmap.end(); ++it )
delete it->second;
{
try {
delete it->second;
}catch(...){}
}
delete it1->second;
}
......@@ -193,7 +199,8 @@ void MBExchange::waitSMReady()
ostringstream err;
err << myname << "(waitSMReady): failed waiting SharedMemory " << ready_timeout << " msec";
dcrit << err.str() << endl;
throw SystemError(err.str());
if( checkProcActive() )
throw SystemError(err.str());
}
}
// -----------------------------------------------------------------------------
......@@ -233,7 +240,15 @@ void MBExchange::sigterm( int signo )
{
dwarn << myname << ": ********* SIGTERM(" << signo << ") ********" << endl;
setProcActive(false);
UniSetObject_LT::sigterm(signo);
try
{
UniSetObject_LT::sigterm(signo);
}
catch( ... )
{
// std::exception_ptr p = std::current_exception();
// std::clog <<(p ? p.__cxa_exception_type()->name() : "null") << std::endl;
}
}
// ------------------------------------------------------------------------------------------
void MBExchange::readConfiguration()
......@@ -1507,7 +1522,7 @@ void MBExchange::updateMTR( RegMap::iterator& rit )
if( r->mtrType == MTR::mtT4 )
{
if( save )
{
{
dwarn << myname << "(updateMTR): write (T4) reg(" << dat2str(r->mbreg) << ") to MTR NOT YET!!!" << endl;
}
else
......@@ -2547,14 +2562,14 @@ void MBExchange::sysCommand( const UniSetTypes::SystemMessage *sm )
string fname(ulog.getLogFile());
if( !fname.empty() )
{
ulog.logFile(fname);
ulog.logFile(fname,true);
ulog << myname << "(sysCommand): ***************** ulog LOG ROTATE *****************" << std::endl;
}
dlog << myname << "(sysCommand): logRotate" << std::endl;
fname = dlog.getLogFile();
if( !fname.empty() )
{
dlog.logFile(fname);
dlog.logFile(fname,true);
dlog << myname << "(sysCommand): ***************** dlog LOG ROTATE *****************" << std::endl;
}
}
......@@ -2580,7 +2595,8 @@ void MBExchange::askSensors( UniversalIO::UIOCommand cmd )
dcrit << err.str() << endl;
kill(SIGTERM,getpid()); // прерываем (перезапускаем) процесс...
throw SystemError(err.str());
// throw SystemError(err.str());
return;
}
try
......
......@@ -75,6 +75,12 @@ pollThread(0)
// -----------------------------------------------------------------------------
MBTCPMaster::~MBTCPMaster()
{
if( pollThread )
{
pollThread->stop();
if( pollThread->isRunning() )
pollThread->join();
}
delete pollThread;
//delete mbtcp;
}
......@@ -146,12 +152,20 @@ void MBTCPMaster::poll_thread()
if( sidExchangeMode != DefaultObjectId && force )
exchangeMode = shm->localGetValue(itExchangeMode,sidExchangeMode);
}
catch(...){}
catch(...)
{
throw;
}
try
{
poll();
}
catch(...){}
catch(...)
{
// if( !checkProcActive() )
throw;
}
if( !checkProcActive() )
break;
......@@ -160,6 +174,36 @@ void MBTCPMaster::poll_thread()
}
}
// -----------------------------------------------------------------------------
void MBTCPMaster::sigterm( int signo )
{
setProcActive(false);
if( pollThread )
{
pollThread->stop();
if( pollThread->isRunning() )
pollThread->join();
delete pollThread;
pollThread = 0;
}
try
{
MBExchange::sigterm(signo);
}
catch( const std::exception& ex )
{
cerr << "catch: " << ex.what() << endl;
}
catch( ... )
{
std::exception_ptr p = std::current_exception();
std::clog <<(p ? p.__cxa_exception_type()->name() : "null") << std::endl;
}
}
// -----------------------------------------------------------------------------
void MBTCPMaster::help_print( int argc, const char* const* argv )
{
cout << "Default: prefix='mbtcp'" << endl;
......
......@@ -208,6 +208,7 @@ class MBTCPMaster:
protected:
virtual void sysCommand( const UniSetTypes::SystemMessage *sm ) override;
virtual std::shared_ptr<ModbusClient> initMB( bool reopen=false ) override;
virtual void sigterm( int signo ) override;
UniSetTypes::uniset_rwmutex mbMutex;
std::string iaddr;
......
......@@ -78,9 +78,12 @@ int main( int argc, const char** argv )
}
catch(...)
{
std::exception_ptr p = std::current_exception();
std::clog <<(p ? p.__cxa_exception_type()->name() : "null") << std::endl;
dcrit << "(mbtcpmaster): catch ..." << std::endl;
}
on_sigchild(SIGTERM);
on_sigchild(SIGTERM);
return 1;
}
......@@ -9,106 +9,106 @@ using namespace MTR;
// --------------------------------------------------------------------------
static void print_help()
{
printf("Usage: mtrconv TYPE[T1...T12,T16,T17] hex1 hex2\n");
printf("Usage: mtrconv TYPE[T1...T12,T16,T17] hex1 hex2\n");
}
// --------------------------------------------------------------------------
int main( int argc, const char **argv )
{
unsigned short v1 = 0;
unsigned short v2 = 0;
const char* type="";
unsigned short v1 = 0;
unsigned short v2 = 0;
const char* type="";
if( argc<2 )
{
print_help();
return 1;
}
if( argc<2 )
{
print_help();
return 1;
}
type = argv[1];
v1 = UniSetTypes::uni_atoi(argv[2]);
type = argv[1];
v1 = UniSetTypes::uni_atoi(argv[2]);
if( argc>=4 )
{
v1 = UniSetTypes::uni_atoi(argv[3]);
v2 = UniSetTypes::uni_atoi(argv[2]);
}
if( argc>=4 )
{
v1 = UniSetTypes::uni_atoi(argv[3]);
v2 = UniSetTypes::uni_atoi(argv[2]);
}
if( !strcmp(type,"T1") )
cout << "(T1): v1=" << v1 << " --> (unsigned) " << v1 << endl;
else if( !strcmp(type,"T2") )
cout << "(T2): v1=" << v1 << " --> (signed) " << (signed short)v1 << endl;
else if( !strcmp(type,"T16") )
{
T16 t(v1);
cout << "(T16): v1=" << t.val << " float=" << t.fval << endl;
}
else if( !strcmp(type,"T17") )
{
T17 t(v1);
cout << "(T17): v1=" << t.val << " float=" << t.fval << endl;
}
else if( !strcmp(type,"T3") )
{
T3 t(v1,v2);
cout << "(T3): v1=" << t.raw.v[0] << " v2=" << t.raw.v[1]
<< " --> " << t << endl;
}
else if( !strcmp(type,"T4") )
{
T4 t(v1);
cout << "(T4): v1=" << t.raw
<< " --> " << t << endl;
}
else if( !strcmp(type,"T5") )
{
T5 t(v1,v2);
cout << "(T5): v1=" << t.raw.v[0] << " v2=" << t.raw.v[1]
<< " --> " << t << endl;
}
else if( !strcmp(type,"T6") )
{
T6 t(v1,v2);
cout << "(T6): v1=" << t.raw.v[0] << " v2=" << t.raw.v[1]
<< " --> " << t << endl;
}
else if( !strcmp(type,"T7") )
{
T7 t(v1,v2);
cout << "(T7): v1=" << t.raw.v[0] << " v2=" << t.raw.v[1]
// << " --> " << T7.val << " * 10^-4"
<< " ===> " << t << endl;
}
else if( !strcmp(type,"T8") )
{
T8 t(v1,v2);
cout << "(T8): v1=" << t.raw.v[0] << " v2=" << t.raw.v[1]
<< " ===> " << t << endl;
}
else if( !strcmp(type,"T9") )
{
T9 t(v1,v2);
cout << "(T9): v1=" << t.raw.v[0] << " v2=" << t.raw.v[1]
<< " ===> " << t << endl;
}
else if( !strcmp(type,"T10") )
{
T10 t(v1,v2);
cout << "(T10): v1=" << t.raw.v[0] << " v2=" << t.raw.v[1]
<< " ===> " << t << endl;
}
else if( !strcmp(type,"F1") )
{
F1 f(v1,v2);
cout << "(F1): v1=" << f.raw.v[0] << " v2=" << f.raw.v[1]
<< " ===> " << f.raw.val << endl;
}
else
{
cout << " Unknown type: " << type << endl;
return 1;
}
if( !strcmp(type,"T1") )
cout << "(T1): v1=" << v1 << " --> (unsigned) " << v1 << endl;
else if( !strcmp(type,"T2") )
cout << "(T2): v1=" << v1 << " --> (signed) " << (signed short)v1 << endl;
else if( !strcmp(type,"T16") )
{
T16 t(v1);
cout << "(T16): v1=" << t.val << " float=" << t.fval << endl;
}
else if( !strcmp(type,"T17") )
{
T17 t(v1);
cout << "(T17): v1=" << t.val << " float=" << t.fval << endl;
}
else if( !strcmp(type,"T3") )
{
T3 t(v1,v2);
cout << "(T3): v1=" << t.raw.v[0] << " v2=" << t.raw.v[1]
<< " --> " << t << endl;
}
else if( !strcmp(type,"T4") )
{
T4 t(v1);
cout << "(T4): v1=" << t.raw
<< " --> " << t << endl;
}
else if( !strcmp(type,"T5") )
{
T5 t(v1,v2);
cout << "(T5): v1=" << t.raw.v[0] << " v2=" << t.raw.v[1]
<< " --> " << t << endl;
}
else if( !strcmp(type,"T6") )
{
T6 t(v1,v2);
cout << "(T6): v1=" << t.raw.v[0] << " v2=" << t.raw.v[1]
<< " --> " << t << endl;
}
else if( !strcmp(type,"T7") )
{
T7 t(v1,v2);
cout << "(T7): v1=" << t.raw.v[0] << " v2=" << t.raw.v[1]
// << " --> " << T7.val << " * 10^-4"
<< " ===> " << t << endl;
}
else if( !strcmp(type,"T8") )
{
T8 t(v1,v2);
cout << "(T8): v1=" << t.raw.v[0] << " v2=" << t.raw.v[1]
<< " ===> " << t << endl;
}
else if( !strcmp(type,"T9") )
{
T9 t(v1,v2);
cout << "(T9): v1=" << t.raw.v[0] << " v2=" << t.raw.v[1]
<< " ===> " << t << endl;
}
else if( !strcmp(type,"T10") )
{
T10 t(v1,v2);
cout << "(T10): v1=" << t.raw.v[0] << " v2=" << t.raw.v[1]
<< " ===> " << t << endl;
}
else if( !strcmp(type,"F1") )
{
F1 f(v1,v2);
cout << "(F1): v1=" << f.raw.v[0] << " v2=" << f.raw.v[1]
<< " ===> " << f.raw.val << endl;
}
else
{
cout << " Unknown type: " << type << endl;
return 1;
}
return 0;
return 0;
}
// --------------------------------------------------------------------------
......@@ -12,398 +12,398 @@ using namespace UniSetTypes;
using namespace std;
// --------------------------------------------------------------------------
static struct option longopts[] = {
{ "help", no_argument, 0, 'h' },
{ "read03", required_argument, 0, 'r' },
{ "read04", required_argument, 0, 'x' },
{ "read-model", required_argument, 0, 'm' },
{ "read-serial", required_argument, 0, 'n' },
{ "device", required_argument, 0, 'd' },
{ "verbose", no_argument, 0, 'v' },
{ "speed", required_argument, 0, 's' },
{ "use485F", no_argument, 0, 'y' },
{ "num-cycles", required_argument, 0, 'l' },
{ "timeout", required_argument, 0, 't' },
{ NULL, 0, 0, 0 }
{ "help", no_argument, 0, 'h' },
{ "read03", required_argument, 0, 'r' },
{ "read04", required_argument, 0, 'x' },
{ "read-model", required_argument, 0, 'm' },
{ "read-serial", required_argument, 0, 'n' },
{ "device", required_argument, 0, 'd' },
{ "verbose", no_argument, 0, 'v' },
{ "speed", required_argument, 0, 's' },
{ "use485F", no_argument, 0, 'y' },
{ "num-cycles", required_argument, 0, 'l' },
{ "timeout", required_argument, 0, 't' },
{ NULL, 0, 0, 0 }
};
// --------------------------------------------------------------------------
static void print_help()
{
printf("-h|--help - this message\n");
printf("[--read03] slaveaddr reg mtrtype - read from MTR (mtrtype: T1...T10,T16,T17,F1)\n");
printf("[--read04] slaveaddr reg mtrtype - read from MTR (mtrtype: T1...T10,T16,T17,F1)\n");
printf("[-m|--read-model] slaveaddr - read model name from MTR\n");
printf("[-n|--read-serial] slaveaddr - read serial number from MTR\n");
printf("[-y|--use485F] - use RS485 Fastwel.\n");
printf("[-d|--device] dev - use device dev. Default: /dev/ttyS0\n");
printf("[-s|--speed] speed - 9600,14400,19200,38400,57600,115200. Default: 38400.\n");
printf("[-t|--timeout] msec - Timeout. Default: 2000.\n");
printf("[-l|--num-cycles] num - Number of cycles of exchange. Default: -1 infinitely.\n");
printf("[-v|--verbose] - Print all messages to stdout\n");
printf("-h|--help - this message\n");
printf("[--read03] slaveaddr reg mtrtype - read from MTR (mtrtype: T1...T10,T16,T17,F1)\n");
printf("[--read04] slaveaddr reg mtrtype - read from MTR (mtrtype: T1...T10,T16,T17,F1)\n");
printf("[-m|--read-model] slaveaddr - read model name from MTR\n");
printf("[-n|--read-serial] slaveaddr - read serial number from MTR\n");
printf("[-y|--use485F] - use RS485 Fastwel.\n");
printf("[-d|--device] dev - use device dev. Default: /dev/ttyS0\n");
printf("[-s|--speed] speed - 9600,14400,19200,38400,57600,115200. Default: 38400.\n");
printf("[-t|--timeout] msec - Timeout. Default: 2000.\n");
printf("[-l|--num-cycles] num - Number of cycles of exchange. Default: -1 infinitely.\n");
printf("[-v|--verbose] - Print all messages to stdout\n");
}
// --------------------------------------------------------------------------
enum Command
{
cmdNOP,
cmdRead03,
cmdRead04,
cmdModel,
cmdSerial
cmdNOP,
cmdRead03,
cmdRead04,
cmdModel,
cmdSerial
};
// --------------------------------------------------------------------------
static char* checkArg( int ind, int argc, char* argv[] );
static void readMTR( ModbusRTUMaster* mb, ModbusRTU::ModbusAddr addr,
ModbusRTU::ModbusData reg, MTR::MTRType t, Command cmd );
ModbusRTU::ModbusData reg, MTR::MTRType t, Command cmd );
// --------------------------------------------------------------------------
int main( int argc, char **argv )
{
Command cmd = cmdNOP;
int optindex = 0;
int opt = 0;
int verb = 0;
string dev("/dev/ttyS0");
string speed("38400");
ModbusRTU::ModbusData reg = 0;
ModbusRTU::ModbusAddr slaveaddr = 0x00;
int tout = 2000;
DebugStream dlog;
// string tofile("");
int use485 = 0;
int ncycles = -1;
MTR::MTRType mtrtype = MTR::mtUnknown;
try
{
while( (opt = getopt_long(argc, argv, "hvyq:r:d:s:t:x:m:n:",longopts,&optindex)) != -1 )
{
switch (opt)
{
case 'h':
print_help();
return 0;
case 'r':
case 'x':
{
if( opt == 'r' )
cmd = cmdRead03;
else
cmd = cmdRead04;
slaveaddr = ModbusRTU::str2mbAddr( optarg );
if( !checkArg(optind,argc,argv) )
{
cerr << "no argument is given: 'reg'.." << endl;
return 1;
}
reg = ModbusRTU::str2mbData(argv[optind]);
if( !checkArg(optind+1,argc,argv) )
{
cerr << "no argument is given: 'mtrtype'.." << endl;
return 1;
}
mtrtype = MTR::str2type(argv[optind+1]);
if( mtrtype == MTR::mtUnknown )
{
cerr << "command error: Unknown mtr type: '" << string(argv[optind+1]) << "'" << endl;
return 1;
}
}
break;
case 'm':
{
cmd = cmdModel;
slaveaddr = ModbusRTU::str2mbAddr( optarg );
}
break;
case 'n':
{
cmd = cmdSerial;
slaveaddr = ModbusRTU::str2mbAddr( optarg );
}
break;
case 'y':
use485 = 1;
break;
case 'd':
dev = string(optarg);
break;
case 's':
speed = string(optarg);
break;
case 't':
tout = uni_atoi(optarg);
break;
case 'v':
verb = 1;
break;
case 'l':
ncycles = uni_atoi(optarg);
break;
case '?':
default:
printf("? argumnet\n");
return 0;
}
}
if( verb )
{
cout << "(init): dev=" << dev << " speed=" << speed
<< " timeout=" << tout << " msec "
<< endl;
}
ModbusRTUMaster mb(dev,use485);
if( verb )
dlog.addLevel(Debug::ANY);
mb.setTimeout(tout);
mb.setSpeed(speed);
mb.setLog(dlog);
int nc = 1;
if( ncycles > 0 )
nc = ncycles;
while( nc )
{
try
{
switch(cmd)
{
case cmdRead03:
case cmdRead04:
{
if( verb )
{
cout << " slaveaddr=" << ModbusRTU::addr2str(slaveaddr)
<< " reg=" << ModbusRTU::dat2str(reg) << "(" << (int)reg << ")"
<< " mtrType=" << MTR::type2str(mtrtype)
<< endl;
}
readMTR( &mb, slaveaddr, reg, mtrtype, cmd );
}
break;
case cmdModel:
{
if( verb )
{
cout << " read model name: slaveaddr=" << ModbusRTU::addr2str(slaveaddr)
<< endl;
}
string s(MTR::getModelNumber(&mb, slaveaddr));
cout << (s.empty()? "Don`t read model name.":s) << endl;
return 0;
}
break;
case cmdSerial:
{
if( verb )
{
cout << " read serial number: slaveaddr=" << ModbusRTU::addr2str(slaveaddr)
<< endl;
}
string s(MTR::getSerialNumber(&mb, slaveaddr));
cout << (s.empty()? "Don`t read serial number.":s) << endl;
return 0;
}
break;
case cmdNOP:
default:
cerr << "No command. Use -h for help." << endl;
return 1;
}
}
Command cmd = cmdNOP;
int optindex = 0;
int opt = 0;
int verb = 0;
string dev("/dev/ttyS0");
string speed("38400");
ModbusRTU::ModbusData reg = 0;
ModbusRTU::ModbusAddr slaveaddr = 0x00;
int tout = 2000;
DebugStream dlog;
// string tofile("");
int use485 = 0;
int ncycles = -1;
MTR::MTRType mtrtype = MTR::mtUnknown;
try
{
while( (opt = getopt_long(argc, argv, "hvyq:r:d:s:t:x:m:n:",longopts,&optindex)) != -1 )
{
switch (opt)
{
case 'h':
print_help();
return 0;
case 'r':
case 'x':
{
if( opt == 'r' )
cmd = cmdRead03;
else
cmd = cmdRead04;
slaveaddr = ModbusRTU::str2mbAddr( optarg );
if( !checkArg(optind,argc,argv) )
{
cerr << "no argument is given: 'reg'.." << endl;
return 1;
}
reg = ModbusRTU::str2mbData(argv[optind]);
if( !checkArg(optind+1,argc,argv) )
{
cerr << "no argument is given: 'mtrtype'.." << endl;
return 1;
}
mtrtype = MTR::str2type(argv[optind+1]);
if( mtrtype == MTR::mtUnknown )
{
cerr << "command error: Unknown mtr type: '" << string(argv[optind+1]) << "'" << endl;
return 1;
}
}
break;
case 'm':
{
cmd = cmdModel;
slaveaddr = ModbusRTU::str2mbAddr( optarg );
}
break;
case 'n':
{
cmd = cmdSerial;
slaveaddr = ModbusRTU::str2mbAddr( optarg );
}
break;
case 'y':
use485 = 1;
break;
case 'd':
dev = string(optarg);
break;
case 's':
speed = string(optarg);
break;
case 't':
tout = uni_atoi(optarg);
break;
case 'v':
verb = 1;
break;
case 'l':
ncycles = uni_atoi(optarg);
break;
case '?':
default:
printf("? argumnet\n");
return 0;
}
}
if( verb )
{
cout << "(init): dev=" << dev << " speed=" << speed
<< " timeout=" << tout << " msec "
<< endl;
}
ModbusRTUMaster mb(dev,use485);
if( verb )
dlog.addLevel(Debug::ANY);
mb.setTimeout(tout);
mb.setSpeed(speed);
mb.setLog(dlog);
int nc = 1;
if( ncycles > 0 )
nc = ncycles;
while( nc )
{
try
{
switch(cmd)
{
case cmdRead03:
case cmdRead04:
{
if( verb )
{
cout << " slaveaddr=" << ModbusRTU::addr2str(slaveaddr)
<< " reg=" << ModbusRTU::dat2str(reg) << "(" << (int)reg << ")"
<< " mtrType=" << MTR::type2str(mtrtype)
<< endl;
}
readMTR( &mb, slaveaddr, reg, mtrtype, cmd );
}
break;
case cmdModel:
{
if( verb )
{
cout << " read model name: slaveaddr=" << ModbusRTU::addr2str(slaveaddr)
<< endl;
}
string s(MTR::getModelNumber(&mb, slaveaddr));
cout << (s.empty()? "Don`t read model name.":s) << endl;
return 0;
}
break;
case cmdSerial:
{
if( verb )
{
cout << " read serial number: slaveaddr=" << ModbusRTU::addr2str(slaveaddr)
<< endl;
}
string s(MTR::getSerialNumber(&mb, slaveaddr));
cout << (s.empty()? "Don`t read serial number.":s) << endl;
return 0;
}
break;
case cmdNOP:
default:
cerr << "No command. Use -h for help." << endl;
return 1;
}
}
catch( ModbusRTU::mbException& ex )
{
if( ex.err != ModbusRTU::erTimeOut )
throw;
{
if( ex.err != ModbusRTU::erTimeOut )
throw;
cout << "timeout..." << endl;
cout << "timeout..." << endl;
}
if( ncycles > 0 )
{
nc--;
if( nc <=0 )
break;
}
if( ncycles > 0 )
{
nc--;
if( nc <=0 )
break;
}
msleep(500);
}
}
msleep(500);
}
}
catch( ModbusRTU::mbException& ex )
{
cerr << "(mtr-read): " << ex << endl;
}
catch(SystemError& err)
{
cerr << "(mtr-read): " << err << endl;
}
catch(Exception& ex)
{
cerr << "(mtr-read): " << ex << endl;
}
catch(...)
{
cerr << "(mtr-read): catch(...)" << endl;
}
return 0;
{
cerr << "(mtr-read): " << ex << endl;
}
catch(SystemError& err)
{
cerr << "(mtr-read): " << err << endl;
}
catch(Exception& ex)
{
cerr << "(mtr-read): " << ex << endl;
}
catch(...)
{
cerr << "(mtr-read): catch(...)" << endl;
}
return 0;
}
// --------------------------------------------------------------------------
char* checkArg( int i, int argc, char* argv[] )
{
if( i<argc && (argv[i])[0]!='-' )
return argv[i];
if( i<argc && (argv[i])[0]!='-' )
return argv[i];
return 0;
return 0;
}
// --------------------------------------------------------------------------
void readMTR( ModbusRTUMaster* mb, ModbusRTU::ModbusAddr addr,
ModbusRTU::ModbusData reg, MTR::MTRType mtrType, Command cmd )
ModbusRTU::ModbusData reg, MTR::MTRType mtrType, Command cmd )
{
int count = MTR::wsize(mtrType);
ModbusRTU::ModbusData dat[ModbusRTU::MAXLENPACKET/sizeof(ModbusRTU::ModbusData)];
memset(dat,0,sizeof(dat));
if( cmd == cmdRead03 )
{
ModbusRTU::ReadOutputRetMessage ret = mb->read03(addr,reg,count);
memcpy(dat,ret.data,sizeof(ModbusRTU::ModbusData)*ret.count);
}
else if( cmd == cmdRead04 )
{
ModbusRTU::ReadInputRetMessage ret = mb->read04(addr,reg,count);
memcpy(dat,ret.data,sizeof(ModbusRTU::ModbusData)*ret.count);
}
else
{
cerr << "Unknown command..." << endl;
return;
}
if( mtrType == MTR::mtT1 )
{
MTR::T1 t(dat[0]);
cout << "(T1): v1=" << dat[0] << " --> (unsigned) " << t.val << endl;
return;
}
if( mtrType == MTR::mtT2 )
{
MTR::T2 t(dat[0]);
cout << "(T2): v1=" << dat[0] << " --> (signed) " << t.val << endl;
return;
}
if( mtrType == MTR::mtT3 )
{
MTR::T3 t(dat,MTR::T3::wsize());
cout << "(T3): v1=" << t.raw.v[0] << " v2=" << t.raw.v[1]
<< " --> " << t << endl;
return;
}
if( mtrType == MTR::mtT4 )
{
MTR::T4 t(dat[0]);
cout << "(T4): v1=" << t.raw
<< " --> " << t << endl;
return;
}
if( mtrType == MTR::mtT5 )
{
MTR::T5 t(dat,MTR::T5::wsize());
cout << "(T5): v1=" << t.raw.v[0] << " v2=" << t.raw.v[1]
<< " --> " << t << endl;
return;
}
if( mtrType == MTR::mtT6 )
{
MTR::T6 t(dat,MTR::T6::wsize());
cout << "(T6): v1=" << t.raw.v[0] << " v2=" << t.raw.v[1]
<< " --> " << t << endl;
return;
}
if( mtrType == MTR::mtT7 )
{
MTR::T7 t(dat,MTR::T7::wsize());
cout << "(T7): v1=" << t.raw.v[0] << " v2=" << t.raw.v[1]
<< " ===> " << t << endl;
return;
}
if( mtrType == MTR::mtT16 )
{
MTR::T16 t(dat[0]);
cout << "(T16): v1=" << t.val << " float=" << t.fval << endl;
return;
}
if( mtrType == MTR::mtT17 )
{
MTR::T17 t(dat[0]);
cout << "(T17): v1=" << t.val << " float=" << t.fval << endl;
return;
}
if( mtrType == MTR::mtF1 )
{
MTR::F1 f(dat,MTR::F1::wsize());
cout << "(F1): v1=" << f.raw.v[0] << " v2=" << f.raw.v[1]
<< " ===> " << f << endl;
return;
}
if( mtrType == MTR::mtT8 )
{
MTR::T8 t(dat,MTR::T8::wsize());
cout << "(T8): v1=" << t.raw.v[0] << " v2=" << t.raw.v[1]
<< " ===> " << t << endl;
return;
}
if( mtrType == MTR::mtT9 )
{
MTR::T9 t(dat,MTR::T9::wsize());
cout << "(T9): v1=" << t.raw.v[0] << " v2=" << t.raw.v[1]
<< " ===> " << t << endl;
return;
}
if( mtrType == MTR::mtT10 )
{
MTR::T10 t(dat,MTR::T10::wsize());
cout << "(T10): v1=" << t.raw.v[0] << " v2=" << t.raw.v[1]
<< " ===> " << t << endl;
return;
}
cerr << "Unsupported mtrtype='" << MTR::type2str(mtrType) << "'" << endl;
int count = MTR::wsize(mtrType);
ModbusRTU::ModbusData dat[ModbusRTU::MAXLENPACKET/sizeof(ModbusRTU::ModbusData)];
memset(dat,0,sizeof(dat));
if( cmd == cmdRead03 )
{
ModbusRTU::ReadOutputRetMessage ret = mb->read03(addr,reg,count);
memcpy(dat,ret.data,sizeof(ModbusRTU::ModbusData)*ret.count);
}
else if( cmd == cmdRead04 )
{
ModbusRTU::ReadInputRetMessage ret = mb->read04(addr,reg,count);
memcpy(dat,ret.data,sizeof(ModbusRTU::ModbusData)*ret.count);
}
else
{
cerr << "Unknown command..." << endl;
return;
}
if( mtrType == MTR::mtT1 )
{
MTR::T1 t(dat[0]);
cout << "(T1): v1=" << dat[0] << " --> (unsigned) " << t.val << endl;
return;
}
if( mtrType == MTR::mtT2 )
{
MTR::T2 t(dat[0]);
cout << "(T2): v1=" << dat[0] << " --> (signed) " << t.val << endl;
return;
}
if( mtrType == MTR::mtT3 )
{
MTR::T3 t(dat,MTR::T3::wsize());
cout << "(T3): v1=" << t.raw.v[0] << " v2=" << t.raw.v[1]
<< " --> " << t << endl;
return;
}
if( mtrType == MTR::mtT4 )
{
MTR::T4 t(dat[0]);
cout << "(T4): v1=" << t.raw
<< " --> " << t << endl;
return;
}
if( mtrType == MTR::mtT5 )
{
MTR::T5 t(dat,MTR::T5::wsize());
cout << "(T5): v1=" << t.raw.v[0] << " v2=" << t.raw.v[1]
<< " --> " << t << endl;
return;
}
if( mtrType == MTR::mtT6 )
{
MTR::T6 t(dat,MTR::T6::wsize());
cout << "(T6): v1=" << t.raw.v[0] << " v2=" << t.raw.v[1]
<< " --> " << t << endl;
return;
}
if( mtrType == MTR::mtT7 )
{
MTR::T7 t(dat,MTR::T7::wsize());
cout << "(T7): v1=" << t.raw.v[0] << " v2=" << t.raw.v[1]
<< " ===> " << t << endl;
return;
}
if( mtrType == MTR::mtT16 )
{
MTR::T16 t(dat[0]);
cout << "(T16): v1=" << t.val << " float=" << t.fval << endl;
return;
}
if( mtrType == MTR::mtT17 )
{
MTR::T17 t(dat[0]);
cout << "(T17): v1=" << t.val << " float=" << t.fval << endl;
return;
}
if( mtrType == MTR::mtF1 )
{
MTR::F1 f(dat,MTR::F1::wsize());
cout << "(F1): v1=" << f.raw.v[0] << " v2=" << f.raw.v[1]
<< " ===> " << f << endl;
return;
}
if( mtrType == MTR::mtT8 )
{
MTR::T8 t(dat,MTR::T8::wsize());
cout << "(T8): v1=" << t.raw.v[0] << " v2=" << t.raw.v[1]
<< " ===> " << t << endl;
return;
}
if( mtrType == MTR::mtT9 )
{
MTR::T9 t(dat,MTR::T9::wsize());
cout << "(T9): v1=" << t.raw.v[0] << " v2=" << t.raw.v[1]
<< " ===> " << t << endl;
return;
}
if( mtrType == MTR::mtT10 )
{
MTR::T10 t(dat,MTR::T10::wsize());
cout << "(T10): v1=" << t.raw.v[0] << " v2=" << t.raw.v[1]
<< " ===> " << t << endl;
return;
}
cerr << "Unsupported mtrtype='" << MTR::type2str(mtrType) << "'" << endl;
}
......@@ -4,7 +4,7 @@
--confile test.xml \
--mbtcp-name MBMaster1 \
--smemory-id SharedMemory \
--dlog-add-levels info,crit,warn,level4,level3 \
--dlog-add-levels system,info,crit,warn,level4,level3 \
--mbtcp-set-prop-prefix \
--mbtcp-filter-field rs \
--mbtcp-filter-value 5 \
......
......@@ -9,114 +9,114 @@ using namespace VTypes;
// --------------------------------------------------------------------------
static void print_help()
{
printf("Usage: vtconv TYPE[F2|F4|I2|U2] hex1 hex2 [hex3 hex4]\n");
printf("Usage: vtconv TYPE[F2|F4|I2|U2] hex1 hex2 [hex3 hex4]\n");
}
// --------------------------------------------------------------------------
int main( int argc, const char **argv )
{
/*
VTypes::F2 f2;
f2.raw.val = 2.345;
cout << "Example(F2): float=" << f2.raw.val
<< " regs:"
<< " v[0]=" << f2.raw.v[0]
<< " v[1]=" << f2.raw.v[1]
<< endl;
VTypes::F4 f4;
f4.raw.val = 2.345123123;
cout << "Example(F4): float=" << f4.raw.val
<< " regs:"
<< " v[0]=" << f4.raw.v[0]
<< " v[1]=" << f4.raw.v[1]
<< " v[2]=" << f4.raw.v[2]
<< " v[3]=" << f4.raw.v[3]
<< endl;
cout << "-------------" << endl << endl;
VTypes::I2 i2;
i2.raw.val = -6553004;
cout << "Example(I2): int=" << i2.raw.val
<< " regs:"
<< " v[0]=" << i2.raw.v[0]
<< " v[1]=" << i2.raw.v[1]
<< endl;
cout << "-------------" << endl << endl;
VTypes::U2 u2;
u2.raw.val = 655300400;
cout << "Example(U2): unsigned int=" << u2.raw.val
<< " regs:"
<< " v[0]=" << u2.raw.v[0]
<< " v[1]=" << u2.raw.v[1]
<< endl;
cout << "-------------" << endl << endl;
// return 0;
VTypes::F2 f2;
f2.raw.val = 2.345;
cout << "Example(F2): float=" << f2.raw.val
<< " regs:"
<< " v[0]=" << f2.raw.v[0]
<< " v[1]=" << f2.raw.v[1]
<< endl;
VTypes::F4 f4;
f4.raw.val = 2.345123123;
cout << "Example(F4): float=" << f4.raw.val
<< " regs:"
<< " v[0]=" << f4.raw.v[0]
<< " v[1]=" << f4.raw.v[1]
<< " v[2]=" << f4.raw.v[2]
<< " v[3]=" << f4.raw.v[3]
<< endl;
cout << "-------------" << endl << endl;
VTypes::I2 i2;
i2.raw.val = -6553004;
cout << "Example(I2): int=" << i2.raw.val
<< " regs:"
<< " v[0]=" << i2.raw.v[0]
<< " v[1]=" << i2.raw.v[1]
<< endl;
cout << "-------------" << endl << endl;
VTypes::U2 u2;
u2.raw.val = 655300400;
cout << "Example(U2): unsigned int=" << u2.raw.val
<< " regs:"
<< " v[0]=" << u2.raw.v[0]
<< " v[1]=" << u2.raw.v[1]
<< endl;
cout << "-------------" << endl << endl;
// return 0;
*/
unsigned short v[4];
memset(v,0,sizeof(v));
const char* type="";
if( argc<3 )
{
print_help();
return 1;
}
type = argv[1];
v[0] = UniSetTypes::uni_atoi(argv[2]);
if( argc>3 )
v[1] = UniSetTypes::uni_atoi(argv[3]);
if( argc>4 )
v[2] = UniSetTypes::uni_atoi(argv[4]);
if( argc>5 )
v[3] = UniSetTypes::uni_atoi(argv[5]);
if( !strcmp(type,"F2") )
{
VTypes::F2 f(v,sizeof(v));
cout << "(F2): v[0]=" << v[0]
<< " v[1]=" << v[1]
<< " --> (float) " << (float)f << endl;
}
else if( !strcmp(type,"F4") )
{
VTypes::F4 f(v,sizeof(v));
cout << "(F4): v[0]=" << v[0]
<< " v[1]=" << v[1]
<< " v[2]=" << v[2]
<< " v[3]=" << v[3]
<< " --> (float) " << (float)f << endl;
}
else if( !strcmp(type,"I2") )
{
VTypes::I2 i(v,sizeof(v));
cout << "(I2): v[0]=" << v[0]
<< " v[1]=" << v[1]
<< " --> (int) " << (int)i << endl;
}
else if( !strcmp(type,"U2") )
{
VTypes::U2 i(v,sizeof(v));
cout << "(U2): v[0]=" << v[0]
<< " v[1]=" << v[1]
<< " --> (unsigned int) " << (unsigned int)i << endl;
}
else
{
cout << " Unknown type: " << type << endl;
}
return 0;
unsigned short v[4];
memset(v,0,sizeof(v));
const char* type="";
if( argc<3 )
{
print_help();
return 1;
}
type = argv[1];
v[0] = UniSetTypes::uni_atoi(argv[2]);
if( argc>3 )
v[1] = UniSetTypes::uni_atoi(argv[3]);
if( argc>4 )
v[2] = UniSetTypes::uni_atoi(argv[4]);
if( argc>5 )
v[3] = UniSetTypes::uni_atoi(argv[5]);
if( !strcmp(type,"F2") )
{
VTypes::F2 f(v,sizeof(v));
cout << "(F2): v[0]=" << v[0]
<< " v[1]=" << v[1]
<< " --> (float) " << (float)f << endl;
}
else if( !strcmp(type,"F4") )
{
VTypes::F4 f(v,sizeof(v));
cout << "(F4): v[0]=" << v[0]
<< " v[1]=" << v[1]
<< " v[2]=" << v[2]
<< " v[3]=" << v[3]
<< " --> (float) " << (float)f << endl;
}
else if( !strcmp(type,"I2") )
{
VTypes::I2 i(v,sizeof(v));
cout << "(I2): v[0]=" << v[0]
<< " v[1]=" << v[1]
<< " --> (int) " << (int)i << endl;
}
else if( !strcmp(type,"U2") )
{
VTypes::U2 i(v,sizeof(v));
cout << "(U2): v[0]=" << v[0]
<< " v[1]=" << v[1]
<< " --> (unsigned int) " << (unsigned int)i << endl;
}
else
{
cout << " Unknown type: " << type << endl;
}
return 0;
}
// --------------------------------------------------------------------------
......@@ -623,7 +623,7 @@ void MBSlave::sysCommand( const UniSetTypes::SystemMessage *sm )
string fname(ulog.getLogFile());
if( !fname.empty() )
{
ulog.logFile(fname);
ulog.logFile(fname,true);
ulog << myname << "(sysCommand): ***************** ulog LOG ROTATE *****************" << std::endl;
}
......@@ -631,7 +631,7 @@ void MBSlave::sysCommand( const UniSetTypes::SystemMessage *sm )
fname = dlog.getLogFile();
if( !fname.empty() )
{
dlog.logFile(fname);
dlog.logFile(fname,true);
dlog << myname << "(sysCommand): ***************** dlog LOG ROTATE *****************" << std::endl;
}
}
......
......@@ -264,7 +264,7 @@ CORBA::Boolean SharedMemory::exist()
// ------------------------------------------------------------------------------------------
void SharedMemory::sigterm( int signo )
{
if( signo == SIGTERM )
if( signo == SIGTERM && wdt )
wdt->stop();
// raise(SIGKILL);
IONotifyController_LT::sigterm(signo);
......
......@@ -16,15 +16,47 @@
#ifdef UNISET_ENABLE_IO
#include "IOControl.h"
#endif
#include "LogAgregator.h"
#include "LogServer.h"
// --------------------------------------------------------------------------
using namespace std;
using namespace UniSetTypes;
using namespace UniSetExtensions;
// --------------------------------------------------------------------------
const int MaxAddNum = 10;
const unsigned int MaxAddNum = 10;
// --------------------------------------------------------------------------
static void help_print( int argc, const char* argv[] );
static LogServer* run_logserver( const std::string& cnamem, DebugStream& log );
static LogServer* logserver = 0;
#ifdef UNISET_ENABLE_IO
std::list< ThreadCreator<IOControl>* > lst_iothr;
#endif
// --------------------------------------------------------------------------
void activator_terminate( int signo )
{
if( logserver )
{
try
{
delete logserver;
logserver = 0;
}
catch(...){}
}
#ifdef UNISET_IO_ENABLE
for( auto& i: lst_iothr )
{
try
{
i->stop();
}
catch(...){}
}
#endif
}
// --------------------------------------------------------------------------
int main( int argc, const char **argv )
{
if( argc>1 && ( strcmp(argv[1],"--help")==0 || strcmp(argv[1],"-h")==0 ) )
......@@ -45,6 +77,7 @@ int main( int argc, const char **argv )
conf->initDebug(UniSetExtensions::dlog,"dlog");
UniSetActivator* act = UniSetActivator::Instance();
act->signal_terminate_event().connect( &activator_terminate );
// ------------ SharedMemory ----------------
SharedMemory* shm = SharedMemory::init_smemory(argc,argv);
if( shm == NULL )
......@@ -54,7 +87,7 @@ int main( int argc, const char **argv )
#ifdef UNISET_ENABLE_IO
// ------------ IOControl ----------------
std::list< ThreadCreator<IOControl>* > lst_iothr;
// std::list< ThreadCreator<IOControl>* > lst_iothr;
for( unsigned int i=0; i<MaxAddNum; i++ )
{
stringstream s;
......@@ -122,7 +155,7 @@ int main( int argc, const char **argv )
stringstream p;
p << "mbs";
if( i > 0 ) p << i;
if( dlog.is_info() )
dlog.info() << "(smemory-plus): add MBSlave(" << p.str() << ")" << endl;
......@@ -180,13 +213,24 @@ int main( int argc, const char **argv )
act->broadcast( sm.transport_msg() );
#ifdef UNISET_IO_ENABLE
for( std::list< ThreadCreator<IOControl>* >::iterator it=lst_iothr.begin(); it!=lst_iothr.end(); ++it )
(*it)->start();
for( auto& i: lst_iothr )
i->start();
#endif
LogAgregator la;
la.add(ulog);
la.add(dlog);
logserver = run_logserver("smplus",la);
if( logserver == 0 )
{
cerr << "(smemory-plus): run logserver for 'smplus' FAILED" << endl;
return 1;
}
act->run(false);
on_sigchild(SIGTERM);
on_sigchild(SIGTERM);
return 0;
}
catch(Exception& ex)
......@@ -240,3 +284,48 @@ void help_print( int argc, const char* argv[] )
cout << "--confile - Use confile. Default: configure.xml" << endl;
cout << "--logfile - Use logfile. Default: smemory-plus.log" << endl;
}
// -----------------------------------------------------------------------------
LogServer* run_logserver( const std::string& cname, DebugStream& log )
{
const UniXML* xml = UniSetTypes::conf->getConfXML();
xmlNode* cnode = UniSetTypes::conf->findNode(xml->getFirstNode(),"LogServer",cname);
if( cnode == 0 )
{
cerr << "(init_ulogserver): Not found xmlnode for '" << cname << "'" << endl;
return 0;
}
UniXML::iterator it(cnode);
LogServer* ls = new LogServer( log );
timeout_t sessTimeout = conf->getArgPInt("--" + cname + "-session-timeout",it.getProp("sessTimeout"),3600000);
timeout_t cmdTimeout = conf->getArgPInt("--" + cname + "-cmd-timeout",it.getProp("cmdTimeout"),2000);
timeout_t outTimeout = conf->getArgPInt("--" + cname + "-out-timeout",it.getProp("outTimeout"),2000);
ls->setSessionTimeout(sessTimeout);
ls->setCmdTimeout(cmdTimeout);
ls->setOutTimeout(outTimeout);
std::string host = conf->getArgParam("--" + cname + "-host",it.getProp("host"));
if( host.empty() )
{
cerr << "(init_ulogserver): " << cname << ": unknown host.." << endl;
delete ls;
return 0;
}
ost::tpport_t port = conf->getArgPInt("--" + cname + "-port",it.getProp("port"),0);
if( port == 0 )
{
cerr << "(init_ulogserver): " << cname << ": unknown port.." << endl;
delete ls;
return 0;
}
cout << "logserver: " << host << ":" << port << endl;
ls->run(host, port, true);
return ls;
}
// -----------------------------------------------------------------------------
......@@ -4,7 +4,6 @@ ulimit -Sc 10000000
START=uniset2-start.sh
${START} -f ./uniset2-smemory-plus --smemory-id SharedMemory --confile test.xml \
--dlog-add-levels any \
--io-name IOControl \
--io-polltime 100 \
--io-s-filter-field io \
......@@ -31,6 +30,8 @@ ${START} -f ./uniset2-smemory-plus --smemory-id SharedMemory --confile test.xml
--mbtcp2-gateway-port 2049 \
--mbtcp2-recv-timeout 200 \
--mbtcp2-force-out 1 \
--ulog-add-levels system \
$*
# --add-rtu \
# --rs-dev /dev/cbsideA1 \
# --rs-id RTUExchange \
......
......@@ -523,7 +523,7 @@ void UNetExchange::sysCommand( const UniSetTypes::SystemMessage *sm )
string fname(ulog.getLogFile());
if( !fname.empty() )
{
ulog.logFile(fname);
ulog.logFile(fname,true);
ulog << myname << "(sysCommand): ***************** ulog LOG ROTATE *****************" << std::endl;
}
......@@ -531,7 +531,7 @@ void UNetExchange::sysCommand( const UniSetTypes::SystemMessage *sm )
fname = dlog.getLogFile();
if( !fname.empty() )
{
dlog.logFile(fname);
dlog.logFile(fname,true);
dlog << myname << "(sysCommand): ***************** dlog LOG ROTATE *****************" << std::endl;
}
}
......
......@@ -26,7 +26,7 @@ namespace UniSetExtensions
Calibration* buildCalibrationDiagram( const std::string& dname );
void on_sigchild( int sig );
void on_sigchild( int sig );
extern DebugStream dlog;
}
......
......@@ -21,24 +21,24 @@
#include "DebugStream.h"
// -----------------------------------------------------------------------------
class UObject_SK:
public UniSetObject,
public LT_Object
public UniSetObject,
public LT_Object
{
public:
UObject_SK( UniSetTypes::ObjectId id, xmlNode* node=UniSetTypes::conf->getNode("UObject"), const std::string& argprefix="" );
UObject_SK();
virtual ~UObject_SK();
bool alarm( UniSetTypes::ObjectId sid, bool state );
long getValue( UniSetTypes::ObjectId sid );
void setValue( UniSetTypes::ObjectId sid, long value );
void askSensor( UniSetTypes::ObjectId sid, UniversalIO::UIOCommand, UniSetTypes::ObjectId node = UniSetTypes::conf->getLocalNode() );
void updateValues();
void setMsg( UniSetTypes::ObjectId code, bool state );
DebugStream mylog;
void init_dlog( DebugStream& d );
public:
UObject_SK( UniSetTypes::ObjectId id, xmlNode* node=UniSetTypes::conf->getNode("UObject"), const std::string& argprefix="" );
UObject_SK();
virtual ~UObject_SK();
bool alarm( UniSetTypes::ObjectId sid, bool state );
long getValue( UniSetTypes::ObjectId sid );
void setValue( UniSetTypes::ObjectId sid, long value );
void askSensor( UniSetTypes::ObjectId sid, UniversalIO::UIOCommand, UniSetTypes::ObjectId node = UniSetTypes::conf->getLocalNode() );
void updateValues();
void setMsg( UniSetTypes::ObjectId code, bool state );
DebugStream mylog;
void init_dlog( DebugStream& d );
// "синтаксический сахар"..для логов
#define myinfo if( mylog.debugging(Debug::INFO) ) mylog
......@@ -55,86 +55,86 @@ class UObject_SK:
#define mylog9 if( mylog.debugging(Debug::LEVEL9) ) mylog
// Используемые идентификаторы
// Используемые идентификаторы сообщений
// Текущее значение и предыдущее значение
// --- public variables ---
// --- end of public variables ---
protected:
// --- protected variables ---
// ---- end of protected variables ----
virtual void callback();
virtual void processingMessage( UniSetTypes::VoidMessage* msg );
virtual void sysCommand( const UniSetTypes::SystemMessage* sm );
virtual void askSensors( UniversalIO::UIOCommand cmd ){}
virtual void sensorInfo( const UniSetTypes::SensorMessage* sm ){}
virtual void timerInfo( const UniSetTypes::TimerMessage* tm ){}
virtual void sigterm( int signo );
virtual bool activateObject();
virtual void testMode( bool state );
void updatePreviousValues();
void checkSensors();
void updateOutputs( bool force );
void preAskSensors( UniversalIO::UIOCommand cmd );
void preSensorInfo( const UniSetTypes::SensorMessage* sm );
void preTimerInfo( const UniSetTypes::TimerMessage* tm );
void waitSM( int wait_msec, UniSetTypes::ObjectId testID = UniSetTypes::DefaultObjectId );
void resetMsg();
Trigger trResetMsg;
PassiveTimer ptResetMsg;
int resetMsgTime;
// Выполнение очередного шага программы
virtual void step()=0;
int sleep_msec; /*!< пауза между итерациями */
bool active;
UniSetTypes::ObjectId smTestID; /*!< идентификатор датчика для тестирования готовности SM */
// управление датчиком "сердцебиения"
PassiveTimer ptHeartBeat; /*! < период "сердцебиения" */
UniSetTypes::ObjectId idHeartBeat; /*! < идентификатор датчика (AI) "сердцебиения" */
int maxHeartBeat; /*! < сохраняемое значение */
xmlNode* confnode;
/*! получить числовое свойство из конф. файла по привязанной confnode */
int getIntProp(const std::string& name) { return UniSetTypes::conf->getIntProp(confnode, name); }
/*! получить текстовое свойство из конф. файла по привязанной confnode */
inline const std::string getProp(const std::string& name) { return UniSetTypes::conf->getProp(confnode, name); }
int smReadyTimeout; /*!< время ожидания готовности SM */
std::atomic_bool activated;
int activateTimeout; /*!< время ожидания готовности UniSetObject к работе */
PassiveTimer ptStartUpTimeout; /*!< время на блокировку обработки WatchDog, если недавно был StartUp */
int askPause; /*!< пауза между неудачными попытками заказать датчики */
IOController_i::SensorInfo si;
private:
// --- private variables ---
// --- end of private variables ---
bool end_private; // вспомогательное поле (для внутреннего использования при генерировании кода)
// Используемые идентификаторы
// Используемые идентификаторы сообщений
// Текущее значение и предыдущее значение
// --- public variables ---
// --- end of public variables ---
protected:
// --- protected variables ---
// ---- end of protected variables ----
virtual void callback();
virtual void processingMessage( UniSetTypes::VoidMessage* msg );
virtual void sysCommand( const UniSetTypes::SystemMessage* sm );
virtual void askSensors( UniversalIO::UIOCommand cmd ){}
virtual void sensorInfo( const UniSetTypes::SensorMessage* sm ){}
virtual void timerInfo( const UniSetTypes::TimerMessage* tm ){}
virtual void sigterm( int signo );
virtual bool activateObject();
virtual void testMode( bool state );
void updatePreviousValues();
void checkSensors();
void updateOutputs( bool force );
void preAskSensors( UniversalIO::UIOCommand cmd );
void preSensorInfo( const UniSetTypes::SensorMessage* sm );
void preTimerInfo( const UniSetTypes::TimerMessage* tm );
void waitSM( int wait_msec, UniSetTypes::ObjectId testID = UniSetTypes::DefaultObjectId );
void resetMsg();
Trigger trResetMsg;
PassiveTimer ptResetMsg;
int resetMsgTime;
// Выполнение очередного шага программы
virtual void step()=0;
int sleep_msec; /*!< пауза между итерациями */
bool active;
UniSetTypes::ObjectId smTestID; /*!< идентификатор датчика для тестирования готовности SM */
// управление датчиком "сердцебиения"
PassiveTimer ptHeartBeat; /*! < период "сердцебиения" */
UniSetTypes::ObjectId idHeartBeat; /*! < идентификатор датчика (AI) "сердцебиения" */
int maxHeartBeat; /*! < сохраняемое значение */
xmlNode* confnode;
/*! получить числовое свойство из конф. файла по привязанной confnode */
int getIntProp(const std::string& name) { return UniSetTypes::conf->getIntProp(confnode, name); }
/*! получить текстовое свойство из конф. файла по привязанной confnode */
inline const std::string getProp(const std::string& name) { return UniSetTypes::conf->getProp(confnode, name); }
int smReadyTimeout; /*!< время ожидания готовности SM */
std::atomic_bool activated;
int activateTimeout; /*!< время ожидания готовности UniSetObject к работе */
PassiveTimer ptStartUpTimeout; /*!< время на блокировку обработки WatchDog, если недавно был StartUp */
int askPause; /*!< пауза между неудачными попытками заказать датчики */
IOController_i::SensorInfo si;
private:
// --- private variables ---
// --- end of private variables ---
bool end_private; // вспомогательное поле (для внутреннего использования при генерировании кода)
};
// -----------------------------------------------------------------------------
......
......@@ -273,7 +273,7 @@ void UObject_SK::sysCommand( const SystemMessage* _sm )
string fname( mylog.getLogFile() );
if( !fname.empty() )
{
mylog.logFile(fname.c_str());
mylog.logFile(fname.c_str(),true);
mylog << myname << "(sysCommand): ***************** mylog LOG ROTATE *****************" << endl;
}
}
......
......@@ -10,6 +10,7 @@
// but should be adaptable to any project.
// (c) 2002 adapted for UniSet by Lav, GNU GPL license
// Modify for UniSet by pv@eterspft.ru, GNU GPL license
#ifndef DEBUGSTREAM_H
#define DEBUGSTREAM_H
......@@ -20,6 +21,8 @@
#include <iostream>
#include <string>
#include <sigc++/sigc++.h>
#include "Debug.h"
#ifdef TEST_DEBUGSTREAM
#include <string>
......@@ -86,10 +89,13 @@ public:
/// Constructor, sets the log file to f, and the debug level to t.
explicit
DebugStream(char const * f, Debug::type t = Debug::NONE);
DebugStream(char const * f, Debug::type t = Debug::NONE, bool truncate=false );
///
~DebugStream();
virtual ~DebugStream();
typedef sigc::signal<void,const std::string&> StreamEvent_Signal;
StreamEvent_Signal signal_stream_event();
/// Sets the debug level to t.
void level(Debug::type t) {
......@@ -112,7 +118,7 @@ public:
}
/// Sets the debugstreams' logfile to f.
void logFile( const std::string& f );
virtual void logFile( const std::string& f, bool truncate=false );
inline std::string getLogFile(){ return fname; }
......@@ -194,7 +200,13 @@ public:
const DebugStream &operator=(const DebugStream& r);
private:
inline void setLogName( const std::string& n ){ logname = n; }
inline std::string getLogName(){ return logname; }
protected:
void sbuf_overflow( const std::string& s );
// private:
/// The current debug level
Debug::type dt;
/// The no-op stream.
......@@ -206,6 +218,8 @@ private:
bool show_datetime;
std::string fname;
StreamEvent_Signal s_stream;
std::string logname;
};
#endif
#ifndef LogAgregator_H_
#define LogAgregator_H_
// -------------------------------------------------------------------------
#include <string>
#include <list>
#include "DebugStream.h"
#include "LogServerTypes.h"
// -------------------------------------------------------------------------
class LogAgregator:
public DebugStream
{
public:
explicit LogAgregator( Debug::type t = Debug::NONE );
explicit LogAgregator( char const * f, Debug::type t = Debug::NONE );
virtual ~LogAgregator();
virtual void logFile( const std::string& f );
void add( DebugStream& log );
// Управление "подчинёнными" логами
void addLevel( const std::string& logname, Debug::type t );
void delLevel( const std::string& logname, Debug::type t );
void level( const std::string& logname, Debug::type t );
struct LogInfo
{
LogInfo():log(0),logfile(""){}
LogInfo( DebugStream* l ):log(l),logfile(l->getLogFile()){}
DebugStream* log;
std::string logfile;
};
DebugStream* getLog( const std::string& logname );
LogInfo getLogInfo( const std::string& logname );
protected:
void logOnEvent( const std::string& s );
private:
typedef std::list<LogInfo> LogList;
LogList llst;
};
// -------------------------------------------------------------------------
#endif // LogAgregator_H_
// -------------------------------------------------------------------------
#ifndef LogReader_H_
#define LogReader_H_
// -------------------------------------------------------------------------
#include <string>
#include <queue>
#include <cc++/socket.h>
#include "UTCPStream.h"
#include "DebugStream.h"
#include "LogServerTypes.h"
// -------------------------------------------------------------------------
class LogReader
{
public:
LogReader();
~LogReader();
void readlogs( const std::string& addr, ost::tpport_t port,
LogServerTypes::Command c = LogServerTypes::cmdNOP,
int data = 0,
const std::string& logname="",
bool verbose = false );
void readlogs( const std::string& addr, ost::tpport_t port, LogServerTypes::lsMessage& m, bool verbose = false );
bool isConnection();
inline void setCommandOnlyMode( bool s ){ cmdonly = s; }
protected:
void connect( const std::string& addr, ost::tpport_t port, timeout_t tout=TIMEOUT_INF );
void connect( ost::InetAddress addr, ost::tpport_t port, timeout_t tout=TIMEOUT_INF );
void disconnect();
private:
UTCPStream* tcp;
std::string iaddr;
ost::tpport_t port;
bool cmdonly;
DebugStream rlog;
};
// -------------------------------------------------------------------------
#endif // LogReader_H_
// -------------------------------------------------------------------------
// -------------------------------------------------------------------------
#ifndef LogServer_H_
#define LogServer_H_
// -------------------------------------------------------------------------
#include <list>
#include <string>
#include <cc++/socket.h>
#include "Mutex.h"
#include "DebugStream.h"
#include "ThreadCreator.h"
class LogSession;
// -------------------------------------------------------------------------
/*! \page pgLogServer Лог сервер
Лог сервер предназначен для возможности удалённого чтения логов (DebugStream).
Ему указывается host и port для прослушивания запросов, которые можно делать при помощи
LogReader. Читающих клиентов может быть скольугодно много, на каждого создаётся своя "сессия"(LogSession).
При этом через лог сервер имеется возможность управлять включением или отключением определённых уровней логов,
записью, отключением записи или ротацией файла с логами. DebugStream за которым ведётся "слежение"
задаётся в конструкторе для LogServer.
\code
DebugStream mylog;
LogServer logsrv(mylog);
...
logsrv.run(host,port,create_thread);
...
\endcode
При этом если необходимо управлять или читать сразу несколько логов можно воспользоваться специальным классом LogAgregator.
\code
DebugStream log1;
log1.setLogName("log1");
DebugStream log2;
log2.setLogName("log2");
LogAgregator la;
la.add(log1);
la.add(log2);
LogServer logsrv(la);
...
logsrv.run(host,port,create_thread);
...
\endcode
*/
// -------------------------------------------------------------------------
class LogServer
{
public:
LogServer( DebugStream& log );
LogServer( std::ostream& os );
~LogServer();
inline void setSessionTimeout( timeout_t msec ){ sessTimeout = msec; }
inline void setCmdTimeout( timeout_t msec ){ cmdTimeout = msec; }
inline void setOutTimeout( timeout_t msec ){ outTimeout = msec; }
void run( const std::string& addr, ost::tpport_t port, bool thread=true );
protected:
LogServer();
void work();
void sessionFinished( LogSession* s );
private:
typedef std::list<LogSession*> SessionList;
SessionList slist;
UniSetTypes::uniset_rwmutex mutSList;
timeout_t timeout;
timeout_t sessTimeout;
timeout_t cmdTimeout;
timeout_t outTimeout;
std::atomic_bool cancelled;
DebugStream mylog;
ThreadCreator<LogServer>* thr;
ost::TCPSocket* tcp;
DebugStream* elog;
std::ostream* oslog;
};
// -------------------------------------------------------------------------
#endif // LogServer_H_
// -------------------------------------------------------------------------
// -------------------------------------------------------------------------
#ifndef LogServerTypes_H_
#define LogServerTypes_H_
// -------------------------------------------------------------------------
#include <ostream>
#include <cstring>
// -------------------------------------------------------------------------
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){ std::memset(logname,0,sizeof(logname)); }
unsigned int magic;
Command cmd;
unsigned int data;
static const size_t MAXLOGNAME = 20;
char logname[MAXLOGNAME+1]; // +1 reserverd for '\0'
void setLogName( const std::string& name );
// для команды 'cmdSetLogFile'
// static const size_t MAXLOGFILENAME = 200;
// char logfile[MAXLOGFILENAME];
}__attribute__((packed));
std::ostream& operator<<(std::ostream& os, lsMessage& m );
}
// -------------------------------------------------------------------------
#endif // LogServerTypes_H_
// -------------------------------------------------------------------------
// -------------------------------------------------------------------------
#ifndef LogSession_H_
#define LogSession_H_
// -------------------------------------------------------------------------
#include <string>
#include <deque>
#include <cc++/socket.h>
#include "Mutex.h"
#include "DebugStream.h"
#include "PassiveTimer.h"
// -------------------------------------------------------------------------
/*! Реализация "сессии" для клиентов LogServer. */
class LogSession:
public ost::TCPSession
{
public:
LogSession( ost::TCPSocket &server, DebugStream* log, timeout_t sessTimeout=10000, timeout_t cmdTimeout=2000, timeout_t outTimeout=2000, timeout_t delay=2000 );
virtual ~LogSession();
typedef sigc::slot<void, LogSession*> FinalSlot;
void connectFinalSession( FinalSlot sl );
inline std::string getClientAddress(){ return caddr; }
protected:
virtual void run();
virtual void final();
void logOnEvent( const std::string& s );
void readStream();
private:
typedef std::deque<std::string> LogBuffer;
LogBuffer lbuf;
std::string peername;
std::string caddr;
DebugStream* log;
timeout_t sessTimeout;
timeout_t cmdTimeout;
timeout_t outTimeout;
timeout_t delayTime;
PassiveTimer ptSessionTimeout;
FinalSlot slFin;
std::atomic_bool cancelled;
UniSetTypes::uniset_rwmutex mLBuf;
DebugStream slog;
};
// -------------------------------------------------------------------------
#endif // LogSession_H_
// -------------------------------------------------------------------------
......@@ -33,8 +33,8 @@
#include "IONotifyController.h"
// ------------------------------------------------------------------------------------------
/*!
Интерфейс для записи в файл и восстановления из файла списка заказчиков по датчикам для
IONotifyController-а (NC).
Интерфейс для записи в файл и восстановления из файла списка заказчиков по датчикам для
IONotifyController-а (NC).
\note Это абстрактный интерфейс. В чистом виде не используется.
*/
......@@ -108,8 +108,8 @@ class NCRestorer
// ------------------------------------------------------------------------------------------
/*!
* \brief Реализация сохранения списка заказчиков в xml.
Данный класс работает с глобальным xml-файлом проекта (обычно configure.xml),
поэтому НЕ реализаует функции записи (dump)-а.
Данный класс работает с глобальным xml-файлом проекта (обычно configure.xml),
поэтому НЕ реализаует функции записи (dump)-а.
*/
class NCRestorer_XML:
public Restorer_XML,
......
......@@ -177,9 +177,8 @@ template <class ThreadMaster>
void ThreadCreator<ThreadMaster>::run()
{
pid = getpid();
if(m)
(m->*act)();
// PosixThread::stop()
if( m )
(m->*act)();
}
//----------------------------------------------------------------------------------------
template <class ThreadMaster>
......
......@@ -27,6 +27,7 @@
// --------------------------------------------------------------------------
#include <deque>
#include <omniORB4/CORBA.h>
#include <cc++/socket.h>
#include "UniSetTypes.h"
#include "UniSetObject.h"
#include "UniSetManager.h"
......@@ -67,6 +68,9 @@ class UniSetActivator:
virtual UniSetTypes::ObjectType getType() override { return UniSetTypes::ObjectType("UniSetActivator"); }
typedef sigc::signal<void,int> TerminateEvent_Signal;
TerminateEvent_Signal signal_terminate_event();
protected:
/*! Команды доступные при заказе сигналов
......@@ -118,6 +122,7 @@ class UniSetActivator:
ThreadCreator<UniSetActivator> *orbthr;
CORBA::ORB_var orb;
TerminateEvent_Signal s_term;
bool omDestroy;
bool sig;
......
......@@ -77,7 +77,7 @@ class UniSetManager:
virtual bool addManager( UniSetManager *mngr );
virtual bool removeManager( UniSetManager *mngr );
/*! Получение доступа к подчиненному менеджеру по идентификатору
* \return объект ненайден будет возвращен 0.
*/
......
......@@ -11,7 +11,7 @@
class WDTInterface
{
public:
WDTInterface(const std::string& dev);
WDTInterface( const std::string& dev );
~WDTInterface();
bool ping();
......
......@@ -15,10 +15,11 @@ libUniSet2_la_LDFLAGS = -version-info @LIBVER@
libUniSet2_la_LIBADD = -lm \
$(top_builddir)/src/Communications/libCommunications.la \
$(top_builddir)/src/Communications/Modbus/libModbus.la \
$(top_builddir)/src/Communications/TCP/libTCP.la \
$(top_builddir)/src/Interfaces/libInterfaces.la \
$(top_builddir)/src/ObjectRepository/libObjectsRepository.la \
$(top_builddir)/src/Processes/libProcesses.la \
$(top_builddir)/src/Services/libServices.la \
$(top_builddir)/src/Timers/libTimers.la \
$(top_builddir)/src/Various/libVarious.la
$(top_builddir)/src/Various/libVarious.la \
$(top_builddir)/src/Log/libLog.la
############################################################################
# This file is part of the UniSet library #
############################################################################
SUBDIRS=Modbus
SUBDIRS=TCP Modbus
noinst_LTLIBRARIES = libCommunications.la
libCommunications_la_SOURCES = ComPort.cc ComPort485F.cc
......
......@@ -2,10 +2,11 @@
# This file is part of the UniSet library #
############################################################################
noinst_LTLIBRARIES = libModbus.la
libModbus_la_SOURCES = ModbusTypes.cc ModbusHelpers.cc ModbusTCPSession.cc UTCPStream.cc \
libModbus_la_SOURCES = ModbusTypes.cc ModbusHelpers.cc ModbusTCPSession.cc \
ModbusClient.cc ModbusServer.cc ModbusServerSlot.cc \
ModbusRTUSlave.cc ModbusRTUSlaveSlot.cc ModbusRTUMaster.cc \
ModbusTCPCore.cc ModbusTCPServer.cc ModbusTCPServerSlot.cc ModbusTCPMaster.cc TCPCheck.cc
ModbusTCPCore.cc ModbusTCPServer.cc ModbusTCPServerSlot.cc ModbusTCPMaster.cc
libModbus_la_CXXFLAGS = -I$(top_builddir)/include/Communications/modbus $(SIGC_CFLAGS) $(COMCPP_CFLAGS)
#libModbus_la_LIBADD = $(top_builddir)/src/Communications/TCP/libTCP.la $(SIGC_LIBS) $(COMCPP_LIBS)
libModbus_la_LIBADD = $(SIGC_LIBS) $(COMCPP_LIBS)
......@@ -165,7 +165,7 @@ bool ModbusRTU::isWriteFunction( SlaveFunctionCode c )
c == fnForceSingleCoil ||
c == fnForceMultipleCoils )
return true;
return false;
}
// -------------------------------------------------------------------------
......@@ -177,10 +177,10 @@ std::ostream& ModbusRTU::mbPrintMessage( std::ostream& os, ModbusByte* m, int le
// << setiosflags(ios::showbase) // для вывода в формате 0xNN
s << hex << showbase << setfill('0'); // << showbase;
for( unsigned int i=0; i<len; i++ )
for( ssize_t i=0; i<len; i++ )
s << setw(2) << (short)(m[i]) << " ";
// s << "<" << setw(2) << (int)(m[i]) << ">";
return os << s.str();
}
// -------------------------------------------------------------------------
......@@ -965,7 +965,7 @@ ModbusMessage ReadOutputRetMessage::transport_msg()
// Создаём временно массив, переворачиваем байты
ModbusData* dtmp = new ModbusData[count];
for( unsigned int i=0; i<count; i++ )
for( ssize_t i=0; i<count; i++ )
dtmp[i] = SWAPSHORT(data[i]);
// копируем
......@@ -1109,17 +1109,17 @@ void ReadInputRetMessage::init( ModbusMessage& m )
count = cnt;
bcnt = m.data[0];
memcpy(&data,&(m.data[1]),bcnt);
// переворачиваем данные
swapData();
memcpy(&crc,&(m.data[bcnt+1]),szCRC);
}
}
// -------------------------------------------------------------------------
void ReadInputRetMessage::swapData()
{
// переворачиваем данные
for( unsigned int i=0; i<count; i++ )
for( ssize_t i=0; i<count; i++ )
data[i] = SWAPSHORT(data[i]);
}
// -------------------------------------------------------------------------
......@@ -1174,7 +1174,7 @@ ModbusMessage ReadInputRetMessage::transport_msg()
// Создаём временно массив, переворачиваем байты
ModbusData* dtmp = new ModbusData[count];
for( unsigned int i=0; i<count; i++ )
for( ssize_t i=0; i<count; i++ )
dtmp[i] = SWAPSHORT(data[i]);
// копируем
......@@ -1391,7 +1391,7 @@ std::ostream& ModbusRTU::operator<<(std::ostream& os, ForceCoilsMessage& m )
<< " bcnt=" << b2str(m.bcnt)
<< " data[" << (int)m.quant <<"]={ ";
for( unsigned int i=0; i<m.bcnt; i++ )
for( ssize_t i=0; i<m.bcnt; i++ )
{
DataBits d(m.data[i]);
os << "" << d << " ";
......@@ -1539,7 +1539,7 @@ ModbusMessage WriteOutputMessage::transport_msg()
// Создаём временно массив, переворачиваем байты
ModbusData* dtmp = new ModbusData[quant];
for( unsigned int i=0; i<quant; i++ )
for( ssize_t i=0; i<quant; i++ )
dtmp[i] = SWAPSHORT(data[i]);
// копируем данные
......@@ -1606,7 +1606,7 @@ void WriteOutputMessage::init( ModbusMessage& m )
memcpy(&crc,&(m.data[m.len-szCRC]),szCRC);
int count( bcnt/sizeof(ModbusData) );
for( unsigned int i=0; i<count; i++ )
for( ssize_t i=0; i<count; i++ )
data[i] = SWAPSHORT(data[i]);
}
// -------------------------------------------------------------------------
......@@ -1651,7 +1651,7 @@ std::ostream& ModbusRTU::operator<<(std::ostream& os, WriteOutputMessage& m )
<< " bcnt=" << dat2str(m.bcnt)
<< " data[" << (int)m.quant <<"]={ ";
for( unsigned int i=0; i<m.quant; i++ )
for( ssize_t i=0; i<m.quant; i++ )
os << "" << dat2str(m.data[i]) << " ";
os << "}";
......@@ -2178,7 +2178,7 @@ void DiagnosticMessage::init( ModbusMessage& m )
last +=sizeof(ModbusData)*count;
// переворачиваем данные
for( unsigned int i=0; i<count; i++ )
for( ssize_t i=0; i<count; i++ )
data[i] = SWAPSHORT(data[i]);
memcpy(&crc,&(m.data[last]),szCRC);
......@@ -2243,7 +2243,7 @@ ModbusMessage DiagnosticMessage::transport_msg()
// Создаём временно массив, переворачиваем байты
ModbusData* dtmp = new ModbusData[count];
for( unsigned int i=0; i<count; i++ )
for( ssize_t i=0; i<count; i++ )
dtmp[i] = SWAPSHORT(data[i]);
// копируем
......@@ -2294,7 +2294,7 @@ std::ostream& ModbusRTU::operator<<(std::ostream& os, DiagnosticMessage& m )
<< " subf=" << dat2str(m.subf)
<< " data[" << m.count << "]={";
for( unsigned int i=0; i<m.count; i++ )
for( ssize_t i=0; i<m.count; i++ )
os << dat2str(m.data[i]) << " ";
os << "}";
......@@ -2314,7 +2314,7 @@ std::ostream& ModbusRTU::operator<<(std::ostream& os, DiagnosticRetMessage& m )
<< " subf=" << dat2str(m.subf)
<< " data[" << m.count << "]={";
for( unsigned int i=0; i<m.count; i++ )
for( ssize_t i=0; i<m.count; i++ )
os << dat2str(m.data[i]) << " ";
os << "}";
......@@ -2440,7 +2440,7 @@ RDIObjectInfo::RDIObjectInfo( ModbusByte id, ModbusByte* dat, ModbusByte len ):
{
val.reserve(len);
for( unsigned int i=0; i<len; i++ )
for( ssize_t i=0; i<len; i++ )
val.push_back( (char)dat[i] );
}
// -------------------------------------------------------------------------
......@@ -2738,7 +2738,7 @@ ModbusMessage JournalCommandRetMessage::transport_msg()
// --------------------
// копирование с переворотом данных (для ModbusData)
ModbusData* dtmp = new ModbusData[count];
for( unsigned int i=0; i<count; i++ )
for( ssize_t i=0; i<count; i++ )
dtmp[i] = SWAPSHORT(data[i]);
// копируем
......@@ -3240,7 +3240,7 @@ void ReadFileRecordMessage::init( ModbusMessage& m )
memcpy(&crc,&(m.data[m.len-szCRC]),szCRC);
count = bcnt/sizeof(SubRequest);
for( unsigned int i=0; i<count; i++ )
for( ssize_t i=0; i<count; i++ )
{
data[i].numfile = SWAPSHORT(data[i].numfile);
data[i].numrec = SWAPSHORT(data[i].numrec);
......@@ -3440,7 +3440,7 @@ ModbusMessage FileTransferRetMessage::transport_msg()
// копируем предварительный заголовок
ModbusData dhead[] = { numfile, numpacks, packet };
for( unsigned int i=0; i<sizeof(dhead)/sizeof(ModbusData); i++ )
for( size_t i=0; i<sizeof(dhead)/sizeof(ModbusData); i++ )
dhead[i] = SWAPSHORT(dhead[i]);
memcpy(&(mm.data[ind]),dhead,sizeof(dhead));
......@@ -3479,7 +3479,7 @@ std::ostream& ModbusRTU::operator<<(std::ostream& os, FileTransferRetMessage* m
std::ostream& ModbusTCP::operator<<(std::ostream& os, MBAPHeader& m )
{
// m.swapdata();
for( unsigned int i=0; i<sizeof(m); i++ )
for( size_t i=0; i<sizeof(m); i++ )
os << ((unsigned char*)(&m))[i];
// m.swapdata();
return os;
......
############################################################################
# This file is part of the UniSet library #
############################################################################
noinst_LTLIBRARIES = libTCP.la
libTCP_la_SOURCES = UTCPStream.cc TCPCheck.cc
libTCP_la_CXXFLAGS = $(SIGC_CFLAGS) $(COMCPP_CFLAGS)
libTCP_la_LIBADD = $(SIGC_LIBS) $(COMCPP_LIBS)
......@@ -2,7 +2,7 @@
#include <sstream>
#include "UniSetTypes.h"
#include "PassiveTimer.h"
#include "modbus/TCPCheck.h"
#include "TCPCheck.h"
// -----------------------------------------------------------------------------
using namespace std;
// -----------------------------------------------------------------------------
......
......@@ -4,7 +4,7 @@
#include <errno.h>
#include <cstring>
#include <cc++/socket.h>
#include "modbus/UTCPStream.h"
#include "UTCPStream.h"
#include "PassiveTimer.h"
#include "UniSetTypes.h"
// -------------------------------------------------------------------------
......
#ifndef DEBUGEXTBUF_H
#define DEBUGEXTBUF_H
// Created by Lars Gullik Bj�nnes
// Copyright 1999 Lars Gullik Bj�nnes (larsbj@lyx.org)
// Released into the public domain.
......@@ -16,6 +19,7 @@
//#include "DebugStream.h"
#include "Debug.h"
#include "Mutex.h"
//�Since the current C++ lib in egcs does not have a standard implementation
// of basic_streambuf and basic_filebuf we don't have to include this
......@@ -34,6 +38,7 @@ using std::ostream;
using std::streambuf;
using std::streamsize;
using std::filebuf;
using std::stringbuf;
using std::cerr;
using std::ios;
......@@ -127,6 +132,64 @@ private:
streambuf * sb2;
};
/** A streambuf that sends the output to two different streambufs. These
can be any kind of streambufs.
*/
class threebuf : public streambuf {
public:
///
threebuf(streambuf * b1, streambuf * b2, streambuf * b3)
: streambuf(), sb1(b1), sb2(b2), sb3(b3) {}
protected:
#ifdef MODERN_STL_STREAMS
///
virtual int sync() {
sb2->pubsync();
return sb1->pubsync();
}
///
virtual streamsize xsputn(char_type const * p, streamsize n) {
sb2->sputn(p, n);
sb3->sputn(p, n);
return sb1->sputn(p, n);
}
///
virtual int_type overflow(int_type c = traits_type::eof()) {
sb2->sputc(c);
sb3->sputc(c);
return sb1->sputc(c);
}
#else
typedef char char_type;
typedef int int_type;
///
virtual int sync() {
sb2->sync();
sb3->sync();
return sb1->sync();
}
///
virtual streamsize xsputn(char_type const * p, streamsize n) {
sb2->xsputn(p, n);
sb2->xsputn(p, n);
return sb1->xsputn(p, n);
}
///
virtual int_type overflow(int_type c = EOF) {
sb2->overflow(c);
sb3->owerflow(c);
return sb1->overflow(c);
}
#endif
private:
///
streambuf * sb1;
///
streambuf * sb2;
///
streambuf * sb3;
};
///
class debugbuf : public streambuf {
public:
......@@ -168,235 +231,92 @@ private:
streambuf * sb;
};
//--------------------------------------------------------------------------
/// So that public parts of DebugStream does not need to know about filebuf
struct DebugStream::debugstream_internal {
/// Used when logging to file.
filebuf fbuf;
};
//--------------------------------------------------------------------------
/// Constructor, sets the debug level to t.
DebugStream::DebugStream(Debug::type t)
: ostream(new debugbuf(cerr.rdbuf())),
dt(t), nullstream(new nullbuf), internal(0),
show_datetime(true),
fname(""){}
///
class stringsigbuf : public streambuf {
public:
stringsigbuf():sb(new stringbuf())
{
}
//--------------------------------------------------------------------------
/// Constructor, sets the log file to f, and the debug level to t.
DebugStream::DebugStream(char const * f, Debug::type t)
: ostream(new debugbuf(cerr.rdbuf())),
dt(t), nullstream(new nullbuf),
internal(new debugstream_internal),
show_datetime(true),
fname("")
{
internal->fbuf.open(f, ios::out|ios::app);
delete rdbuf(new teebuf(cerr.rdbuf(),
&internal->fbuf));
}
//--------------------------------------------------------------------------
~stringsigbuf()
{
if( sb )
{
delete sb;
sb = 0;
}
}
DebugStream::~DebugStream()
{
delete nullstream.rdbuf(0); // Without this we leak
delete rdbuf(0); // Without this we leak
delete internal;
}
///
stringsigbuf( stringbuf* b )
: streambuf(), sb(b) {}
//--------------------------------------------------------------------------
const DebugStream& DebugStream::operator=( const DebugStream& r )
{
if( r == *this )
return *this;
typedef sigc::signal<void,const std::string&> StrBufOverflow_Signal;
inline StrBufOverflow_Signal signal_overflow(){ return s_overflow; }
dt = r.dt;
show_datetime = r.show_datetime;
fname = r.fname;
if( !r.fname.empty() )
logFile(fname);
return *this;
}
//--------------------------------------------------------------------------
/// Sets the debugstreams' logfile to f.
void DebugStream::logFile( const std::string& f )
{
fname = f;
if (internal) {
internal->fbuf.close();
} else {
internal = new debugstream_internal;
protected:
#ifdef MODERN_STL_STREAMS
///
virtual int sync() {
UniSetTypes::uniset_rwmutex_wrlock l(mut);
return sb->pubsync();
}
internal->fbuf.open(f.c_str(), ios::out|ios::app);
delete rdbuf(new teebuf(cerr.rdbuf(),
&internal->fbuf));
}
//--------------------------------------------------------------------------
std::ostream & DebugStream::debug(Debug::type t)
{
if(dt & t)
{
if( show_datetime )
printDateTime(t);
*this << "(" << std::setfill(' ') << std::setw(6) << t << "): "; // "):\t";
return *this;
///
virtual streamsize xsputn(char_type const * p, streamsize n) {
UniSetTypes::uniset_rwmutex_wrlock l(mut);
streamsize r = sb->sputn(p, n);
s_overflow.emit( sb->str() );
sb->str("");
return r;
}
return nullstream;
}
//--------------------------------------------------------------------------
std::ostream& DebugStream::operator()(Debug::type t)
{
if(dt & t)
return *this;
return nullstream;
}
//--------------------------------------------------------------------------
std::ostream& DebugStream::printDate(Debug::type t, char brk)
{
if(dt && t)
{
time_t GMTime = time(NULL);
struct tm *tms = localtime(&GMTime);
return *this << std::setw(2) << std::setfill('0') << tms->tm_mday << brk
<< std::setw(2) << std::setfill('0') << tms->tm_mon+1 << brk
<< std::setw(4) << std::setfill('0') << tms->tm_year+1900;
///
virtual int_type overflow(int_type c = traits_type::eof()) {
int_type r = sb->sputc(c);
if( r == '\n' )
{
UniSetTypes::uniset_rwmutex_wrlock l(mut);
s_overflow.emit( sb->str() );
sb->str("");
}
return r;
}
return nullstream;
}
//--------------------------------------------------------------------------
std::ostream& DebugStream::printTime(Debug::type t, char brk)
{
if(dt && t)
{
time_t GMTime = time(NULL);
struct tm *tms = localtime(&GMTime);
return *this << std::setw(2) << std::setfill('0') << tms->tm_hour << brk
<< std::setw(2) << std::setfill('0') << tms->tm_min << brk
<< std::setw(2) << std::setfill('0') << tms->tm_sec;
#else
typedef char char_type;
typedef int int_type;
///
virtual int sync() {
return sb->sync();
}
return nullstream;
}
//--------------------------------------------------------------------------
std::ostream& DebugStream::printDateTime(Debug::type t)
{
if(dt & t)
{
time_t GMTime = time(NULL);
struct tm *tms = localtime(&GMTime);
return *this << std::setw(2) << std::setfill('0') << tms->tm_mday << "/"
<< std::setw(2) << std::setfill('0') << tms->tm_mon+1 << "/"
<< std::setw(4) << std::setfill('0') << tms->tm_year+1900 << " "
<< std::setw(2) << std::setfill('0') << tms->tm_hour << ":"
<< std::setw(2) << std::setfill('0') << tms->tm_min << ":"
<< std::setw(2) << std::setfill('0') << tms->tm_sec;
///
virtual streamsize xsputn(char_type const * p, streamsize n) {
return sb->xsputn(p, n);
}
return nullstream;
}
//--------------------------------------------------------------------------
std::ostream& DebugStream::pos(int x, int y)
{
if( !dt )
return nullstream;
return *this << "\033[" << y << ";" << x << "f";
}
//--------------------------------------------------------------------------
//--------------------------------------------------------------------------
//--------------------------------------------------------------------------
#ifdef TEST_DEBUGSTREAM
// Example debug stream
DebugStream debugstream;
int main(int, char **)
{
/**
I have been running some tests on this to see how much overhead
this kind of permanent debug code has. My conclusion is: not
much. In all, but the most time critical code, this will have
close to no impact at all.
In the tests that I have run the use of
if (debugstream.debugging(DebugStream::INFO))
debugstream << "some debug\n";
has close to no overhead when the debug level is not
DebugStream::INFO.
The overhead for
debugstream.debug(DebugStream::INFO) << "some debug\n";
is also very small when the debug level is not
DebugStream::INFO. However the overhead for this will increase
if complex debugging information is output.
The overhead when the debug level is DebugStream::INFO can be
significant, but since we then are running in debug mode it is
of no concern.
Why should we use this instead of the class Error that we already
have? First of all it uses C++ iostream and constructs, secondly
it will be a lot easier to output the debug info that we need
without a lot of manual conversions, thirdly we can now use
iomanipulators and the complete iostream formatting functions.
pluss it will work for all types that have a operator<<
defined, and can be used in functors that take a ostream & as
parameter. And there should be less need for temporary objects.
And one nice bonus is that we get a log file almost for
free.
Some of the names are of course open to modifications. I will try
to use the names we already use in LyX.
*/
// Just a few simple debugs to show how it can work.
debugstream << "Debug level set to Debug::NONE\n";
if (debugstream.debugging()) {
debugstream << "Something must be debugged\n";
}
debugstream.debug(Debug::WARN) << "more debug(WARN)\n";
debugstream.debug(Debug::INFO) << "even more debug(INFO)\n";
debugstream.debug(Debug::CRIT) << "even more debug(CRIT)\n";
debugstream.level(Debug::value("INFO"));
debugstream << "Setting debug level to Debug::INFO\n";
if (debugstream.debugging()) {
debugstream << "Something must be debugged\n";
}
debugstream.debug(Debug::WARN) << "more debug(WARN)\n";
debugstream.debug(Debug::INFO) << "even more debug(INFO)\n";
debugstream.debug(Debug::CRIT) << "even more debug(CRIT)\n";
debugstream.addLevel(Debug::type(Debug::CRIT |
Debug::WARN));
debugstream << "Adding Debug::CRIT and Debug::WARN\n";
debugstream[Debug::WARN] << "more debug(WARN)\n";
debugstream[Debug::INFO] << "even more debug(INFO)\n";
debugstream[Debug::CRIT] << "even more debug(CRIT)\n";
debugstream.delLevel(Debug::INFO);
debugstream << "Removing Debug::INFO\n";
debugstream[Debug::WARN] << "more debug(WARN)\n";
debugstream[Debug::INFO] << "even more debug(INFO)\n";
debugstream[Debug::CRIT] << "even more debug(CRIT)\n";
debugstream.logFile("logfile");
debugstream << "Setting logfile to \"logfile\"\n";
debugstream << "Value: " << 123 << " " << "12\n";
int i = 0;
int * p = new int;
// note: the (void*) is needed on g++ 2.7.x since it does not
// support partial specialization. In egcs this should not be
// needed.
debugstream << "automatic " << &i
<< ", free store " << p << endl;
delete p;
/*
for (int j = 0; j < 200000; ++j) {
DebugStream tmp;
tmp << "Test" << endl;
virtual int_type overflow(int_type c = EOF) {
int_type r = sb->overflow(c);
if( r == '\n' )
{
UniSetTypes::uniset_rwmutex_wrlock l(mut);
s_overflow.emit( sb->str() );
sb->str("");
}
return r;
}
*/
}
#endif
private:
///
StrBufOverflow_Signal s_overflow;
stringbuf* sb;
UniSetTypes::uniset_rwmutex mut;
};
//--------------------------------------------------------------------------
/// So that public parts of DebugStream does not need to know about filebuf
struct DebugStream::debugstream_internal {
/// Used when logging to file.
filebuf fbuf;
stringsigbuf sbuf;
nullbuf nbuf;
};
//--------------------------------------------------------------------------
#endif
\ No newline at end of file
// Created by Lars Gullik Bj�nnes
// Copyright 1999 Lars Gullik Bj�nnes (larsbj@lyx.org)
// Released into the public domain.
// Primarily developed for use in the LyX Project http://www.lyx.org/
// but should be adaptable to any project.
// (c) 2002 adapted for UniSet by Lav, GNU GPL license
//#define TEST_DEBUGSTREAM
#ifdef __GNUG__
#pragma implementation
#endif
//#include "DebugStream.h"
#include "Debug.h"
#include "Mutex.h"
//�Since the current C++ lib in egcs does not have a standard implementation
// of basic_streambuf and basic_filebuf we don't have to include this
// header.
//#define MODERN_STL_STREAMS
#ifdef MODERN_STL_STREAMS
#include <fstream>
#endif
#include <iostream>
#include <sstream>
#include <iomanip>
#include <time.h>
#include <iomanip>
#include "DebugExtBuf.h"
using std::ostream;
using std::streambuf;
using std::streamsize;
using std::filebuf;
using std::stringbuf;
using std::cerr;
using std::ios;
//--------------------------------------------------------------------------
/// Constructor, sets the debug level to t.
DebugStream::DebugStream(Debug::type t)
: ostream(new debugbuf(cerr.rdbuf())),
dt(t), nullstream(new nullbuf), internal(new debugstream_internal),
show_datetime(true),
fname(""),
logname("")
{
delete rdbuf(new teebuf(cerr.rdbuf(),&internal->sbuf));
internal->sbuf.signal_overflow().connect(sigc::mem_fun(*this, &DebugStream::sbuf_overflow));
}
//--------------------------------------------------------------------------
/// Constructor, sets the log file to f, and the debug level to t.
DebugStream::DebugStream(char const * f, Debug::type t, bool truncate )
: ostream(new debugbuf(cerr.rdbuf())),
dt(t), nullstream(new nullbuf),
internal(new debugstream_internal),
show_datetime(true),
fname(""),
logname("")
{
std::ios_base::openmode mode = ios::out;
mode |= truncate ? ios::trunc : ios::app;
internal->fbuf.open(f, mode);
delete rdbuf(new threebuf(cerr.rdbuf(),
&internal->fbuf,&internal->sbuf));
internal->sbuf.signal_overflow().connect(sigc::mem_fun(*this, &DebugStream::sbuf_overflow));
}
//--------------------------------------------------------------------------
void DebugStream::sbuf_overflow( const std::string& s )
{
s_stream.emit(s);
}
//--------------------------------------------------------------------------
DebugStream::~DebugStream()
{
delete nullstream.rdbuf(0); // Without this we leak
delete rdbuf(0); // Without this we leak
delete internal;
}
//--------------------------------------------------------------------------
const DebugStream& DebugStream::operator=( const DebugStream& r )
{
if( r == *this )
return *this;
dt = r.dt;
show_datetime = r.show_datetime;
fname = r.fname;
if( !r.fname.empty() )
logFile(fname);
// s_stream = r.s_stream;
return *this;
}
//--------------------------------------------------------------------------
/// Sets the debugstreams' logfile to f.
void DebugStream::logFile( const std::string& f, bool truncate )
{
fname = f;
if( internal ) {
internal->fbuf.close();
} else {
internal = new debugstream_internal;
}
if( !f.empty() )
{
std::ios_base::openmode mode = ios::out;
mode |= truncate ? ios::trunc : ios::app;
internal->fbuf.open(f.c_str(), mode);
delete rdbuf(new threebuf(cerr.rdbuf(),
&internal->fbuf,&internal->sbuf));
}
else
delete rdbuf(new teebuf(cerr.rdbuf(),&internal->sbuf));
}
//--------------------------------------------------------------------------
std::ostream & DebugStream::debug(Debug::type t)
{
if(dt & t)
{
if( show_datetime )
printDateTime(t);
*this << "(" << std::setfill(' ') << std::setw(6) << t << "): "; // "):\t";
return *this;
}
return nullstream;
}
//--------------------------------------------------------------------------
std::ostream& DebugStream::operator()(Debug::type t)
{
if(dt & t)
return *this;
return nullstream;
}
//--------------------------------------------------------------------------
std::ostream& DebugStream::printDate(Debug::type t, char brk)
{
if(dt && t)
{
time_t GMTime = time(NULL);
struct tm *tms = localtime(&GMTime);
return *this << std::setw(2) << std::setfill('0') << tms->tm_mday << brk
<< std::setw(2) << std::setfill('0') << tms->tm_mon+1 << brk
<< std::setw(4) << std::setfill('0') << tms->tm_year+1900;
}
return nullstream;
}
//--------------------------------------------------------------------------
std::ostream& DebugStream::printTime(Debug::type t, char brk)
{
if(dt && t)
{
time_t GMTime = time(NULL);
struct tm *tms = localtime(&GMTime);
return *this << std::setw(2) << std::setfill('0') << tms->tm_hour << brk
<< std::setw(2) << std::setfill('0') << tms->tm_min << brk
<< std::setw(2) << std::setfill('0') << tms->tm_sec;
}
return nullstream;
}
//--------------------------------------------------------------------------
std::ostream& DebugStream::printDateTime(Debug::type t)
{
if(dt & t)
{
time_t GMTime = time(NULL);
struct tm *tms = localtime(&GMTime);
return *this << std::setw(2) << std::setfill('0') << tms->tm_mday << "/"
<< std::setw(2) << std::setfill('0') << tms->tm_mon+1 << "/"
<< std::setw(4) << std::setfill('0') << tms->tm_year+1900 << " "
<< std::setw(2) << std::setfill('0') << tms->tm_hour << ":"
<< std::setw(2) << std::setfill('0') << tms->tm_min << ":"
<< std::setw(2) << std::setfill('0') << tms->tm_sec;
}
return nullstream;
}
//--------------------------------------------------------------------------
std::ostream& DebugStream::pos(int x, int y)
{
if( !dt )
return nullstream;
return *this << "\033[" << y << ";" << x << "f";
}
//--------------------------------------------------------------------------
DebugStream::StreamEvent_Signal DebugStream::signal_stream_event()
{
return s_stream;
}
//--------------------------------------------------------------------------
//--------------------------------------------------------------------------
//--------------------------------------------------------------------------
#ifdef TEST_DEBUGSTREAM
// Example debug stream
DebugStream debugstream;
int main(int, char **)
{
/**
I have been running some tests on this to see how much overhead
this kind of permanent debug code has. My conclusion is: not
much. In all, but the most time critical code, this will have
close to no impact at all.
In the tests that I have run the use of
if (debugstream.debugging(DebugStream::INFO))
debugstream << "some debug\n";
has close to no overhead when the debug level is not
DebugStream::INFO.
The overhead for
debugstream.debug(DebugStream::INFO) << "some debug\n";
is also very small when the debug level is not
DebugStream::INFO. However the overhead for this will increase
if complex debugging information is output.
The overhead when the debug level is DebugStream::INFO can be
significant, but since we then are running in debug mode it is
of no concern.
Why should we use this instead of the class Error that we already
have? First of all it uses C++ iostream and constructs, secondly
it will be a lot easier to output the debug info that we need
without a lot of manual conversions, thirdly we can now use
iomanipulators and the complete iostream formatting functions.
pluss it will work for all types that have a operator<<
defined, and can be used in functors that take a ostream & as
parameter. And there should be less need for temporary objects.
And one nice bonus is that we get a log file almost for
free.
Some of the names are of course open to modifications. I will try
to use the names we already use in LyX.
*/
// Just a few simple debugs to show how it can work.
debugstream << "Debug level set to Debug::NONE\n";
if (debugstream.debugging()) {
debugstream << "Something must be debugged\n";
}
debugstream.debug(Debug::WARN) << "more debug(WARN)\n";
debugstream.debug(Debug::INFO) << "even more debug(INFO)\n";
debugstream.debug(Debug::CRIT) << "even more debug(CRIT)\n";
debugstream.level(Debug::value("INFO"));
debugstream << "Setting debug level to Debug::INFO\n";
if (debugstream.debugging()) {
debugstream << "Something must be debugged\n";
}
debugstream.debug(Debug::WARN) << "more debug(WARN)\n";
debugstream.debug(Debug::INFO) << "even more debug(INFO)\n";
debugstream.debug(Debug::CRIT) << "even more debug(CRIT)\n";
debugstream.addLevel(Debug::type(Debug::CRIT |
Debug::WARN));
debugstream << "Adding Debug::CRIT and Debug::WARN\n";
debugstream[Debug::WARN] << "more debug(WARN)\n";
debugstream[Debug::INFO] << "even more debug(INFO)\n";
debugstream[Debug::CRIT] << "even more debug(CRIT)\n";
debugstream.delLevel(Debug::INFO);
debugstream << "Removing Debug::INFO\n";
debugstream[Debug::WARN] << "more debug(WARN)\n";
debugstream[Debug::INFO] << "even more debug(INFO)\n";
debugstream[Debug::CRIT] << "even more debug(CRIT)\n";
debugstream.logFile("logfile");
debugstream << "Setting logfile to \"logfile\"\n";
debugstream << "Value: " << 123 << " " << "12\n";
int i = 0;
int * p = new int;
// note: the (void*) is needed on g++ 2.7.x since it does not
// support partial specialization. In egcs this should not be
// needed.
debugstream << "automatic " << &i
<< ", free store " << p << endl;
delete p;
/*
for (int j = 0; j < 200000; ++j) {
DebugStream tmp;
tmp << "Test" << endl;
}
*/
}
#endif
#include "DebugExtBuf.h"
#include "LogAgregator.h"
// -------------------------------------------------------------------------
LogAgregator::LogAgregator( char const * f, Debug::type t ):
DebugStream(f,t)
{
delete rdbuf(new teebuf(&internal->fbuf,&internal->sbuf));
}
// -------------------------------------------------------------------------
LogAgregator::LogAgregator( Debug::type t ):
DebugStream(t)
{
delete rdbuf(new teebuf(&internal->nbuf,&internal->sbuf));
}
// -------------------------------------------------------------------------
void LogAgregator::logFile( const std::string& f )
{
DebugStream::logFile(f);
if( !f.empty() )
delete rdbuf(new teebuf(&internal->fbuf,&internal->sbuf));
else
delete rdbuf(new teebuf(&internal->nbuf,&internal->sbuf));
}
// -------------------------------------------------------------------------
LogAgregator::~LogAgregator()
{
}
// -------------------------------------------------------------------------
void LogAgregator::logOnEvent( const std::string& s )
{
(*this) << s;
}
// -------------------------------------------------------------------------
void LogAgregator::add( DebugStream& l )
{
l.signal_stream_event().connect( sigc::mem_fun(this, &LogAgregator::logOnEvent) );
for( LogList::iterator i=llst.begin(); i!=llst.end(); i++ )
{
if( &l == i->log )
return;
}
llst.push_back(&l);
}
// -------------------------------------------------------------------------
void LogAgregator::addLevel( const std::string& logname, Debug::type t )
{
for( auto& i: llst )
{
if( i.log->getLogName() == logname )
{
i.log->addLevel(t);
break;
}
}
}
// -------------------------------------------------------------------------
void LogAgregator::delLevel( const std::string& logname, Debug::type t )
{
for( auto& i: llst )
{
if( i.log->getLogName() == logname )
{
i.log->delLevel(t);
break;
}
}
}
// -------------------------------------------------------------------------
void LogAgregator::level( const std::string& logname, Debug::type t )
{
for( auto& i: llst )
{
if( i.log->getLogName() == logname )
{
i.log->level(t);
break;
}
}
}
// -------------------------------------------------------------------------
DebugStream* LogAgregator::getLog( const std::string& logname )
{
if( logname.empty() )
return 0;
for( auto& i: llst )
{
if( i.log->getLogName() == logname )
return i.log;
}
return 0;
}
// -------------------------------------------------------------------------
LogAgregator::LogInfo LogAgregator::getLogInfo( const std::string& logname )
{
if( logname.empty() )
return LogInfo();
for( auto& i: llst )
{
if( i.log->getLogName() == logname )
return i;
}
return LogInfo();
}
// -------------------------------------------------------------------------
#include <string.h>
#include <errno.h>
#include <iostream>
#include <sstream>
#include "Exceptions.h"
#include "LogReader.h"
#include "UniSetTypes.h"
// -------------------------------------------------------------------------
using namespace std;
using namespace UniSetTypes;
// -------------------------------------------------------------------------
LogReader::LogReader():
tcp(0),
iaddr(""),
cmdonly(false)
{
}
// -------------------------------------------------------------------------
LogReader::~LogReader()
{
if( isConnection() )
disconnect();
}
// -------------------------------------------------------------------------
void LogReader::connect( const std::string& addr, ost::tpport_t _port, timeout_t msec )
{
ost::InetAddress ia(addr.c_str());
connect(ia,_port,msec);
}
// -------------------------------------------------------------------------
void LogReader::connect( ost::InetAddress addr, ost::tpport_t _port, timeout_t msec )
{
if( tcp )
{
(*tcp) << endl;
disconnect();
delete tcp;
tcp = 0;
}
// if( !tcp )
// {
ostringstream s;
s << addr;
iaddr = s.str();
port = _port;
if( rlog.is_info() )
rlog.info() << "(LogReader): connect to " << iaddr << ":" << port << endl;
ost::Thread::setException(ost::Thread::throwException);
try
{
tcp = new UTCPStream();
tcp->create(iaddr,port,true,500);
tcp->setTimeout(msec);
tcp->setKeepAlive(true);
}
catch( std::exception& e )
{
if( rlog.debugging(Debug::CRIT) )
{
ostringstream s;
s << "(LogReader): connection " << s.str() << " error: " << e.what();
rlog.crit() << s.str() << std::endl;
}
delete tcp;
tcp = 0;
}
catch( ... )
{
if( rlog.debugging(Debug::CRIT) )
{
ostringstream s;
s << "(LogReader): connection " << s.str() << " error: catch ...";
rlog.crit() << s.str() << std::endl;
}
}
// }
}
// -------------------------------------------------------------------------
void LogReader::disconnect()
{
if( !tcp )
return;
if( rlog.is_info() )
rlog.info() << iaddr << "(LogReader): disconnect." << endl;
tcp->disconnect();
delete tcp;
tcp = 0;
}
// -------------------------------------------------------------------------
bool LogReader::isConnection()
{
return tcp && tcp->isConnected();
}
// -------------------------------------------------------------------------
void LogReader::readlogs( const std::string& _addr, ost::tpport_t _port, LogServerTypes::Command cmd, int data, const std::string& logname, bool verbose )
{
LogServerTypes::lsMessage msg;
msg.cmd = cmd;
msg.data = data;
msg.setLogName(logname);
readlogs(_addr,_port,msg,verbose );
}
// -------------------------------------------------------------------------
void LogReader::readlogs( const std::string& _addr, ost::tpport_t _port, LogServerTypes::lsMessage& msg, bool verbose )
{
timeout_t inTimeout = 10000;
timeout_t outTimeout = 6000;
timeout_t reconDelay = 5000;
char buf[100001];
if( verbose )
rlog.addLevel(Debug::ANY);
bool send_ok = false;
while( true )
{
if( !isConnection() )
connect(_addr,_port,reconDelay);
if( !isConnection() )
{
rlog.warn() << "**** connection timeout.." << endl;
msleep(reconDelay);
continue;
}
if( !send_ok && msg.cmd != LogServerTypes::cmdNOP )
{
if( tcp->isPending(ost::Socket::pendingOutput,outTimeout) )
{
rlog.info() << "** send command: logname='" << msg.logname << "' cmd='" << msg.cmd << "' data='" << msg.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 ('" << msg.cmd << "' FAILED!" << endl;
if( cmdonly )
{
disconnect();
return;
}
}
while( !cmdonly && tcp->isPending(ost::Socket::pendingInput,inTimeout) )
{
int n = tcp->peek( buf,sizeof(buf)-1 );
if( n > 0 )
{
tcp->read(buf,n);
buf[n] = '\0';
cout << buf;
}
else
break;
}
rlog.warn() << "...connection timeout..." << endl;
send_ok = false; // ??!! делать ли?
disconnect();
}
if( isConnection() )
disconnect();
}
// -------------------------------------------------------------------------
#include <sstream>
#include "LogServer.h"
#include "UniSetTypes.h"
#include "Exceptions.h"
#include "LogSession.h"
// -------------------------------------------------------------------------
using namespace std;
using namespace UniSetTypes;
// -------------------------------------------------------------------------
LogServer::~LogServer()
{
cancelled = true;
if( thr )
{
thr->stop();
if( thr->isRunning() )
thr->join();
delete thr;
}
{
// uniset_rwmutex_wrlock l(mutSList);
for( auto& i: slist )
{
if( i->isRunning() )
delete i;
}
}
delete tcp;
}
// -------------------------------------------------------------------------
LogServer::LogServer( std::ostream& os ):
timeout(TIMEOUT_INF),
sessTimeout(3600000),
cmdTimeout(2000),
outTimeout(2000),
cancelled(false),
thr(0),
tcp(0),
elog(0),
oslog(&os)
{
}
// -------------------------------------------------------------------------
LogServer::LogServer( DebugStream& log ):
timeout(TIMEOUT_INF),
sessTimeout(3600000),
cmdTimeout(2000),
outTimeout(2000),
cancelled(false),
thr(0),
tcp(0),
elog(&log),
oslog(0)
{
}
// -------------------------------------------------------------------------
LogServer::LogServer():
timeout(TIMEOUT_INF),
sessTimeout(3600000),
cmdTimeout(2000),
outTimeout(2000),
cancelled(false),
thr(0),
tcp(0),
elog(0)
{
}
// -------------------------------------------------------------------------
void LogServer::run( const std::string& addr, ost::tpport_t port, bool thread )
{
try
{
ost::InetAddress iaddr(addr.c_str());
tcp = new ost::TCPSocket(iaddr,port);
}
catch( ost::Socket *socket )
{
ost::tpport_t port;
int errnum = socket->getErrorNumber();
ost::InetAddress saddr = (ost::InetAddress)socket->getPeer(&port);
ostringstream err;
err << "socket error " << saddr.getHostname() << ":" << port << " = " << errnum;
if( errnum == ost::Socket::errBindingFailed )
err << "bind failed; port busy" << endl;
else
err << "client socket failed" << endl;
throw SystemError( err.str() );
}
if( !thread )
work();
else
{
thr = new ThreadCreator<LogServer>(this, &LogServer::work);
thr->start();
}
}
// -------------------------------------------------------------------------
void LogServer::work()
{
cancelled = false;
while( !cancelled )
{
try
{
while( !cancelled && tcp->isPendingConnection(timeout) )
{
LogSession* s = new LogSession(*tcp, elog, sessTimeout, cmdTimeout, outTimeout);
{
uniset_rwmutex_wrlock l(mutSList);
slist.push_back(s);
}
s->connectFinalSession( sigc::mem_fun(this, &LogServer::sessionFinished) );
s->detach();
}
}
catch( ost::Socket *socket )
{
ost::tpport_t port;
int errnum = socket->getErrorNumber();
ost::InetAddress saddr = (ost::InetAddress)socket->getPeer(&port);
cerr << "socket error " << saddr.getHostname() << ":" << port << " = " << errnum << endl;
if( errnum == ost::Socket::errBindingFailed )
{
cerr << "bind failed; port busy" << endl;
// ::exit(-1);
}
else
cerr << "client socket failed" << endl;
}
}
cerr << "*** LOG SERVER THREAD STOPPED.." << endl;
{
// uniset_rwmutex_wrlock l(mutSList);
for( auto& i: slist )
i->disconnect();
}
}
// -------------------------------------------------------------------------
void LogServer::sessionFinished( LogSession* s )
{
uniset_rwmutex_wrlock l(mutSList);
for( SessionList::iterator i=slist.begin(); i!=slist.end(); ++i )
{
if( (*i) == s )
{
slist.erase(i);
return;
}
}
}
// -------------------------------------------------------------------------
// -------------------------------------------------------------------------
#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;
}
// -------------------------------------------------------------------------
void LogServerTypes::lsMessage::setLogName( const std::string& name )
{
size_t s = name.size()> MAXLOGNAME ? MAXLOGNAME : name.size();
memcpy( &logname, name.c_str(), s );
logname[s] = '\0';
}
// -------------------------------------------------------------------------
#include <iostream>
#include <string>
#include <sstream>
#include <fcntl.h>
#include <errno.h>
#include <cstring>
#include <cc++/socket.h>
#include "LogSession.h"
#include "UniSetTypes.h"
#include "LogServerTypes.h"
#include "LogAgregator.h"
// -------------------------------------------------------------------------
using namespace std;
using namespace UniSetTypes;
// -------------------------------------------------------------------------
LogSession::~LogSession()
{
cancelled = true;
if( isRunning() )
{
disconnect();
ost::Thread::join();
}
}
// -------------------------------------------------------------------------
LogSession::LogSession( ost::TCPSocket &server, DebugStream* _log, timeout_t _sessTimeout, timeout_t _cmdTimeout, timeout_t _outTimeout, timeout_t _delay ):
TCPSession(server),
peername(""),
caddr(""),
log(_log),
sessTimeout(_sessTimeout),
cmdTimeout(_cmdTimeout),
outTimeout(_outTimeout),
delayTime(_delay),
cancelled(false)
{
//slog.addLevel(Debug::ANY);
log->signal_stream_event().connect( sigc::mem_fun(this, &LogSession::logOnEvent) );
}
// -------------------------------------------------------------------------
void LogSession::logOnEvent( const std::string& s )
{
uniset_rwmutex_wrlock l(mLBuf);
lbuf.push_back(s);
}
// -------------------------------------------------------------------------
void LogSession::run()
{
if( cancelled )
return;
{
ost::tpport_t p;
ost::InetAddress iaddr = getIPV4Peer(&p);
// resolve..
caddr = string( iaddr.getHostname() );
ostringstream s;
s << iaddr << ":" << p;
peername = s.str();
}
if( slog.debugging(Debug::INFO) )
slog[Debug::INFO] << peername << "(run): run thread of sessions.." << endl;
ptSessionTimeout.setTiming(sessTimeout);
setKeepAlive(true);
// setTimeout(sessTimeout);
// Команды могут посылаться только в начале сессии..
if( isPending(Socket::pendingInput, cmdTimeout) )
{
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;
string cmdLogName(msg.logname);
DebugStream* cmdlog = log;
string logfile(log->getLogFile());
if( !cmdLogName.empty () )
{
LogAgregator* lag = dynamic_cast<LogAgregator*>(log);
if( lag )
{
LogAgregator::LogInfo inf = lag->getLogInfo(cmdLogName);
if( inf.log )
{
cmdlog = inf.log;
logfile = inf.logfile;
}
else
{
// если имя задали, но такого лога не нашлось
// то игнорируем команду
cmdlog = 0;
logfile = "";
}
}
else
{
// если имя лога задали, а оно не совпадает с текущим
// игнорируем команду
if( log->getLogFile() != cmdLogName )
{
cmdlog = 0;
logfile = "";
}
}
}
// обрабатываем команды только если нашли log
if( cmdlog )
{
// Обработка команд..
// \warning Работа с логом ведётся без mutex-а, хотя он разделяется отдельными потоками
switch( msg.cmd )
{
case LogServerTypes::cmdSetLevel:
cmdlog->level( (Debug::type)msg.data );
break;
case LogServerTypes::cmdAddLevel:
cmdlog->addLevel( (Debug::type)msg.data );
break;
case LogServerTypes::cmdDelLevel:
cmdlog->delLevel( (Debug::type)msg.data );
break;
case LogServerTypes::cmdRotate:
if( !logfile.empty() )
cmdlog->logFile(logfile,true);
break;
case LogServerTypes::cmdOffLogFile:
{
if( !logfile.empty() )
cmdlog->logFile("");
}
break;
case LogServerTypes::cmdOnLogFile:
{
if( !logfile.empty() )
cmdlog->logFile(logfile);
}
break;
default:
slog.warn() << peername << "(run): Unknown command '" << msg.cmd << "'" << endl;
break;
}
}
}
}
}
cancelled = false;
while( !cancelled && isConnected() ) // !ptSessionTimeout.checkTime()
{
// проверка только ради проверки "целостности" соединения
if( isPending(Socket::pendingInput, 10) )
{
char buf[10];
// проверяем канал..(если данных нет, значит "клиент отвалился"...
if( peek(buf,sizeof(buf)) <=0 )
break;
}
if( isPending(Socket::pendingOutput, outTimeout) )
{
//slog.info() << peername << "(run): send.." << endl;
// ptSessionTimeout.reset();
// чтобы не застревать на посылке в сеть..
// делаем через промежуточный буффер (stringstream)
ostringstream sbuf;
bool send = false;
{
uniset_rwmutex_wrlock l(mLBuf);
if( !lbuf.empty() )
{
slog.info() << peername << "(run): send messages.." << endl;
while( !lbuf.empty() )
{
sbuf << lbuf.front();
lbuf.pop_front();
}
send = true;
}
}
if( send )
{
*tcp() << sbuf.str();
tcp()->sync();
}
// чтобы постоянно не проверять... (надо переделать на condition)
sleep(delayTime);
}
}
if( slog.debugging(Debug::INFO) )
slog[Debug::INFO] << peername << "(run): stop thread of sessions..disconnect.." << endl;
disconnect();
if( slog.debugging(Debug::INFO) )
slog[Debug::INFO] << peername << "(run): thread stopping..." << endl;
}
// -------------------------------------------------------------------------
void LogSession::final()
{
tcp()->sync();
slFin(this);
delete this;
}
// -------------------------------------------------------------------------
void LogSession::connectFinalSession( FinalSlot sl )
{
slFin = sl;
}
// ---------------------------------------------------------------------
############################################################################
# This file is part of the UniSet library #
############################################################################
noinst_LTLIBRARIES = libLog.la
libLog_la_CPPFLAGS = $(SIGC_CFLAGS) $(COMCPP_CFLAGS)
libLog_la_LIBADD = $(SIGC_LIBS) $(COMCPP_LIBS)
libLog_la_SOURCES = DebugStream.cc Debug.cc LogServerTypes.cc LogServer.cc LogSession.cc LogReader.cc LogAgregator.cc
......@@ -2,5 +2,5 @@
# This file is part of the UniSet library #
############################################################################
SUBDIRS=ObjectRepository Processes Interfaces Timers Services Various Communications
SUBDIRS=ObjectRepository Processes Interfaces Timers Services Various Communications Log
......@@ -225,10 +225,10 @@ const ObjectInfo* ObjectIndex_idXML::getObjectInfo( const ObjectId id )
// ------------------------------------------------------------------------------------------
const ObjectInfo* ObjectIndex_idXML::getObjectInfo( const std::string& name )
{
auto it = mok.find(name);
auto it = mok.find(name);
if( it != mok.end() )
return getObjectInfo(it->second);
return NULL;
return NULL;
}
// ------------------------------------------------------------------------------------------
......@@ -48,7 +48,7 @@ using namespace std;
В этом обработчике происходит вызов UniSetActivator::oaDestroy(int signo) для фактического
завершения работы и заказывается сигнал SIG_ALRM на время TERMINATE_TIMEOUT,
c обработчиком UniSetActivator::finishterm в котором происходит
"надежное" прибивание текущего процесса (raise(SIGKILL)). Это сделано на тот случай, если
"надежное" прибивание текущего процесса (kill(getpid(),SIGKILL)). Это сделано на тот случай, если
в oaDestroy произойдет зависание.
*/
// ------------------------------------------------------------------------------------------
......@@ -140,7 +140,7 @@ void UniSetActivator::init()
UniSetActivator::~UniSetActivator()
{
if(!procterm )
if( !procterm )
{
ulogsys << myname << "(destructor): ..."<< endl << flush;
if( !omDestroy )
......@@ -153,7 +153,27 @@ UniSetActivator::~UniSetActivator()
}
if( orbthr )
{
orbthr->stop();
if( orbthr->isRunning() )
orbthr->join();
delete orbthr;
orbthr = 0;
}
#if 0
try
{
if( !CORBA::is_nil(orb) )
{
ulogsys << myname << "(oaDestroy): orb destroy... " << endl;
orb->destroy();
ulogsys << myname << "(oaDestroy): orb destroy ok."<< endl;
}
}
catch(...){}
#endif
}
// ------------------------------------------------------------------------------------------
......@@ -170,30 +190,64 @@ void UniSetActivator::oaDestroy(int signo)
ulogsys << myname << "(oaDestroy): terminate ok. " << endl;
try
{
{
stop();
}
catch(...){}
try
{
deactivateObject();
}
catch(...){}
ulogsys << myname << "(oaDestroy): pman deactivate... " << endl;
pman->deactivate(false,true);
ulogsys << myname << "(oaDestroy): pman deactivate ok. " << endl;
ulogsys << myname << "(oaDestroy): orb destroy... " << endl;
try
ulogsys << myname << "(oaDestroy): orbthr=" << orbthr << endl;
if( orbthr )
{
orb->destroy();
try
{
ulogsys << myname << "(oaDestroy): orb thread stop... " << endl;
orbthr->stop();
if( orbthr->isRunning() )
orbthr->join();
ulogsys << myname << "(oaDestroy): orb thread stop ok. " << endl;
}
catch(...){}
}
catch(...){}
ulogsys << myname << "(oaDestroy): orb destroy ok."<< endl;
try
{
ulogsys << myname << "(stop):: shutdown orb... "<<endl;
orb->shutdown(false);
}
catch(...){}
ulogsys << myname << "(stop): shutdown ok."<< endl;
#if 0
try
{
if( !CORBA::is_nil(orb) )
{
ulogsys << myname << "(oaDestroy): orb destroy... " << endl;
orb->destroy();
ulogsys << myname << "(oaDestroy): orb destroy ok."<< endl;
}
}
catch(...){}
#endif
/*
if( orbthr )
{
delete orbthr;
orbthr = 0;
}
*/
}
// waittermMutex.unlock();
}
......@@ -225,7 +279,7 @@ void UniSetActivator::run(bool thread)
pman->activate();
msleep(50);
set_signals(true);
set_signals(true);
if( thread )
{
uinfo << myname << "(run): запускаемся с созданием отдельного потока... "<< endl;
......@@ -266,16 +320,15 @@ void UniSetActivator::stop()
ulogsys << myname << "(stop): discard request ok."<< endl;
/*
#if 1
try
{
ulogsys << myname << "(stop):: shutdown orb... "<<endl;
orb->shutdown(false);
orb->shutdown(true);
}
catch(...){}
ulogsys << myname << "(stop): shutdown ok."<< endl;
*/
#endif
}
}
......@@ -283,7 +336,7 @@ void UniSetActivator::stop()
void UniSetActivator::work()
{
ulogsys << myname << "(work): запускаем orb на обработку запросов..."<< endl;
ulogsys << myname << "(work): запускаем orb на обработку запросов...(orbthr=" << orbthr << ")" << endl;
try
{
if( orbthr )
......@@ -313,17 +366,17 @@ void UniSetActivator::work()
ucrit << myname << "(work): catch ..." << endl;
}
ulogsys << myname << "(work): orb стоп!!!"<< endl;
ulogsys << myname << "(work): orb thread stopped!" << endl;
/*
ulogsys << myname << "(oaDestroy): orb destroy... " << endl;
try
{
orb->destroy();
}
catch(...){}
ulogsys << myname << "(oaDestroy): orb destroy ok."<< endl;
*/
}
// ------------------------------------------------------------------------------------------
void UniSetActivator::getinfo()
......@@ -356,7 +409,7 @@ void UniSetActivator::sysCommand( const UniSetTypes::SystemMessage *sm )
string fname = ulog.getLogFile();
if( !fname.empty() )
{
ulog.logFile(fname.c_str());
ulog.logFile(fname.c_str(),true);
ulog << myname << "(sysCommand): ***************** ulog LOG ROTATE *****************" << endl;
}
}
......@@ -364,18 +417,8 @@ void UniSetActivator::sysCommand( const UniSetTypes::SystemMessage *sm )
}
}
// -------------------------------------------------------------------------
/*
void UniSetActivator::sig_child(int signo)
{
ulogsys << gActivator->getName() << "(sig_child): дочерний процесс закончил работу...(sig=" << signo << ")" << endl;
while( waitpid(-1, 0, WNOHANG) > 0);
}
*/
// ------------------------------------------------------------------------------------------
void UniSetActivator::set_signals(bool ask)
{
struct sigaction act, oact;
sigemptyset(&act.sa_mask);
sigemptyset(&oact.sa_mask);
......@@ -397,7 +440,7 @@ void UniSetActivator::set_signals(bool ask)
act.sa_handler = terminated;
else
act.sa_handler = SIG_DFL;
sigaction(SIGINT, &act, &oact);
sigaction(SIGTERM, &act, &oact);
sigaction(SIGABRT, &act, &oact);
......@@ -419,10 +462,15 @@ void UniSetActivator::finishterm( int signo )
sigset(SIGALRM, SIG_DFL);
doneterm = 1;
raise(SIGKILL);
kill(getpid(),SIGKILL);
}
}
// ------------------------------------------------------------------------------------------
UniSetActivator::TerminateEvent_Signal UniSetActivator::signal_terminate_event()
{
return s_term;
}
// ------------------------------------------------------------------------------------------
void UniSetActivator::terminated( int signo )
{
if( !signo || doneterm || !gActivator || procterm )
......@@ -447,17 +495,24 @@ void UniSetActivator::terminated( int signo )
alarm(TERMINATE_TIMEOUT);
sigrelse(SIGALRM);
if( gActivator )
{
ulogsys << ( gActivator ? gActivator->getName() : "" ) << "(terminated): call oaDestroy.." << endl;
gActivator->oaDestroy(SIGNO); // gActivator->term(SIGNO);
}
doneterm = 1;
ulogsys << ( gActivator ? gActivator->getName() : "" ) << "(terminated): завершаемся..."<< endl<< flush;
if( gActivator )
{
UniSetActivator::set_signals(false);
delete gActivator;
gActivator = 0;
}
sigset(SIGALRM, SIG_DFL);
raise(SIGNO);
kill(getpid(), SIGNO );
}
}
}
......@@ -467,6 +522,9 @@ void UniSetActivator::normalexit()
{
if( gActivator )
ulogsys << gActivator->getName() << "(default exit): good bye."<< endl << flush;
// std::exception_ptr p = std::current_exception();
// std::clog <<(p ? p.__cxa_exception_type()->name() : "null") << std::endl;
}
void UniSetActivator::normalterminate()
......@@ -474,6 +532,9 @@ void UniSetActivator::normalterminate()
if( gActivator )
ucrit << gActivator->getName() << "(default exception terminate): Никто не выловил исключение!!! Good bye."<< endl<< flush;
// abort();
// std::exception_ptr p = std::current_exception();
// std::clog <<(p ? p.__cxa_exception_type()->name() : "null") << std::endl;
}
// ------------------------------------------------------------------------------------------
void UniSetActivator::term( int signo )
......@@ -490,7 +551,7 @@ void UniSetActivator::term( int signo )
{
ulogsys << myname << "(term): вызываем sigterm()" << endl;
sigterm(signo);
s_term.emit(signo);
ulogsys << myname << "(term): sigterm() ok." << endl;
}
catch(Exception& ex)
......@@ -506,7 +567,5 @@ void UniSetActivator::waitDestroy()
{
while( !doneterm && gActivator )
msleep(50);
gActivator = 0;
}
// ------------------------------------------------------------------------------------------
......@@ -115,9 +115,28 @@ UniSetManager::~UniSetManager()
catch(...){}
try
{
managers(deactiv);
managers(deactiv);
}
catch(...){}
for( auto& i: olist )
{
try
{
delete i;
}
catch(...){}
}
for( auto& i: mlist )
{
try
{
delete i;
}
catch(...){}
}
olist.clear();
mlist.clear();
}
......@@ -350,8 +369,18 @@ bool UniSetManager::deactivateObject()
void UniSetManager::sigterm( int signo )
{
sig=signo;
objects(term);
managers(term);
try
{
objects(term);
}
catch(...){}
try
{
managers(term);
}
catch(...){}
UniSetObject::sigterm(signo);
}
// ------------------------------------------------------------------------------------------
......
......@@ -134,16 +134,27 @@ stCountOfQueueFull(0)
// ------------------------------------------------------------------------------------------
UniSetObject::~UniSetObject()
{
deactivate();
try
{
deactivate();
}
catch(...){}
tmr->terminate();
try
{
tmr->terminate();
}
catch(...){}
if( thr )
{
thr->stop();
if( thr->isRunning() )
thr->join();
try
{
thr->stop();
if( thr->isRunning() )
thr->join();
}
catch(...){}
delete thr;
}
......@@ -621,7 +632,8 @@ bool UniSetObject::deactivate()
}
setActive(false); // завершаем поток обработки сообщений
tmr->stop();
if( tmr )
tmr->stop();
// Очищаем очередь
{ // lock
......@@ -756,8 +768,8 @@ void UniSetObject::work()
if( thr )
msgpid = thr->getTID();
while( isActive() )
callback();
while( isActive() )
callback();
uinfo << myname << ": thread processing messages stopped..." << endl;
}
......@@ -816,10 +828,17 @@ void UniSetObject::processingMessage( UniSetTypes::VoidMessage *msg )
<< " mesg: " << fe.errmsg() << endl;
}
}
catch(...)
catch( const std::exception& ex )
{
ucrit << myname << "(processingMessage): " << ex.what() << endl;
}
/*
catch( ... )
{
ucrit << myname << "(processingMessage): catch..." << endl;
std::exception_ptr p = std::current_exception();
ucrit <<(p ? p.__cxa_exception_type()->name() : "null") << std::endl;
}
*/
}
// ------------------------------------------------------------------------------------------
......
......@@ -719,7 +719,7 @@ IOController_i::ShortIOInfo IOController::getChangedTime( UniSetTypes::ObjectId
err << myname << "(getChangedTime): вход(выход) с именем "
<< conf->oind->getNameById(sid) << " не найден";
uinfo << err.str() << endl;
uinfo << err.str() << endl;
throw IOController_i::NameNotFound(err.str().c_str());
}
// -----------------------------------------------------------------------------
......
......@@ -161,6 +161,6 @@ void NCRestorer::init_depends_signals( IONotifyController* ic )
IOController::ChangeSignal s = ic->signal_change_value(it->second.d_si.id);
s.connect( sigc::mem_fun( &it->second, &IOController::USensorInfo::checkDepend) );
}
}
}
// -----------------------------------------------------------------------------
......@@ -504,16 +504,16 @@ void Configuration::initParameters()
if( confDir.empty() )
confDir = getRootDir();
}
}
}
// Heartbeat init...
xmlNode* cnode = getNode("HeartBeatTime");
if( cnode )
// Heartbeat init...
xmlNode* cnode = getNode("HeartBeatTime");
if( cnode )
{
UniXML_iterator hit(cnode);
heartbeat_msec = hit.getIntProp("msec");
if( heartbeat_msec <= 0 )
heartbeat_msec = 5000;
UniXML_iterator hit(cnode);
heartbeat_msec = hit.getIntProp("msec");
if( heartbeat_msec <= 0 )
heartbeat_msec = 5000;
}
}
// -------------------------------------------------------------------------
......@@ -701,7 +701,10 @@ xmlNode* Configuration::initDebug( DebugStream& deb, const string& _debname )
else
{
if( !getProp(dnode,"name").empty() )
{
debname = getProp(dnode,"name");
deb.setLogName(debname);
}
}
string no_deb("--"+debname+"-no-debug");
......@@ -978,6 +981,7 @@ UniversalIO::IOType Configuration::getIOType( const std::string& name )
void uniset_init( int argc, const char* const* argv, const std::string& xmlfile )
{
string confile = UniSetTypes::getArgParam( "--confile", argc, argv, xmlfile );
ulog.setLogName("ulog");
UniSetTypes::conf = new Configuration(argc, argv, confile);
}
// -------------------------------------------------------------------------
......
......@@ -5,8 +5,8 @@
noinst_LTLIBRARIES = libVarious.la
libVarious_la_CPPFLAGS = $(SIGC_CFLAGS) $(COMCPP_CFLAGS)
libVarious_la_LIBADD = $(SIGC_LIBS) $(COMCPP_LIBS)
libVarious_la_SOURCES = DebugStream.cc Debug.cc UniXML.cc MessageType.cc Configuration.cc \
Restorer_XML.cc RunLock.cc Mutex.cc SViewer.cc SMonitor.cc LT_Object.cc WDTInterface.cc
libVarious_la_SOURCES = UniXML.cc MessageType.cc Configuration.cc \
Restorer_XML.cc RunLock.cc Mutex.cc SViewer.cc SMonitor.cc LT_Object.cc WDTInterface.cc
local-clean:
rm -rf *iSK.cc
#include <time.h>
#include "Debug.h"
#include "UniSetTypes.h"
#include "LogAgregator.h"
using namespace std;
using namespace UniSetTypes;
std::ostringstream ss;
std::ostringstream ss1;
void check_log_signal( const string& s )
{
ss << s;
}
void check_alog_signal( const string& s )
{
ss1 << s;
}
int main( int argc, const char **argv )
{
DebugStream tlog;
tlog.signal_stream_event().connect(&check_log_signal);
tlog.addLevel(Debug::ANY);
tlog[Debug::INFO] << ": [info] ..." << endl;
......@@ -20,5 +37,41 @@ int main( int argc, const char **argv )
if( tlog.is_level1() )
tlog.level1() << ": is level1..." << endl;
cout << "===== Test 1 =====" << endl;
cout << ss.str();
cout << "==================" << endl;
DebugStream log1;
log1.setLogName("log1");
DebugStream log2;
log2.setLogName("log2");
LogAgregator la;
la.signal_stream_event().connect(&check_alog_signal);
la.add(log1);
la.add(log2);
log1 << "log1: test message..." << endl;
log2 << "log2: test message..." << endl;
la << "la: test message.." << endl;
cout << "===== Test 2 =====" << endl;
cout << ss1.str();
cout << "==================" << endl;
DebugStream* l = la.getLog("log1");
if( l != &log1 )
cout << "**** TEST FAILED: LogAgregator::getLog() " << endl;
cout << "===== Test 3 =====" << endl;
tlog.level(Debug::ANY);
tlog.logFile("tlog.log");
tlog << "TEST TEXT" << endl;
tlog.logFile("tlog.log",true);
return 0;
}
......@@ -3,7 +3,7 @@
#include "Mutex.h"
#include "ThreadCreator.h"
#include "UniSetTypes.h"
#include "modbus/TCPCheck.h"
#include "TCPCheck.h"
using namespace std;
using namespace UniSetTypes;
......
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