diff --git a/.gitattributes b/.gitattributes index d6ce0a1d8e7c9b1405ddb49c3859b452353d3875..27d9f343d46e850e87312826b9e1a19bfa8ea8c7 100644 --- a/.gitattributes +++ b/.gitattributes @@ -287,6 +287,18 @@ MAC/GCF/HighLevelTools/UITools/Navigator/scripts/libs/gcf-util.ctl -text svneol= MAC/GCF/HighLevelTools/UITools/Navigator/scripts/libs/gcfnav-configuration-functions.ctl -text svneol=native#application/octet-stream MAC/GCF/HighLevelTools/UITools/Navigator/scripts/libs/gcfnav-functions.ctl -text svneol=native#application/octet-stream MAC/GCF/HighLevelTools/UITools/Navigator/scripts/libs/gcfnav-pmlinterface.ctl -text svneol=native#application/octet-stream +MAC/GCF/LogSys/CLP/Makefile.am -text svneol=native#application/octet-stream +MAC/GCF/LogSys/CLP/src/CodeLoggingProcessor.conf.in -text svneol=native#application/octet-stream +MAC/GCF/LogSys/CLP/src/CodeLoggingProcessor.log_prop.in -text svneol=native#application/octet-stream +MAC/GCF/LogSys/CLP/src/Makefile.am -text svneol=native#application/octet-stream +MAC/GCF/LogSys/KVLogSys/Makefile.am -text svneol=native#application/octet-stream +MAC/GCF/LogSys/KVLogSys/src/KVL_Protocol.prot -text svneol=native#application/octet-stream +MAC/GCF/LogSys/KVLogSys/src/KeyValueLoggerSys.conf.in -text svneol=native#application/octet-stream +MAC/GCF/LogSys/KVLogSys/src/KeyValueLoggerSys.log_prop.in -text svneol=native#application/octet-stream +MAC/GCF/LogSys/KVLogSys/src/Makefile.am -text svneol=native#application/octet-stream +MAC/GCF/LogSys/Makefile.am -text svneol=native#application/octet-stream +MAC/GCF/LogSys/bootstrap -text svneol=native#application/octet-stream +MAC/GCF/LogSys/configure.in -text svneol=native#application/octet-stream MAC/GCF/Protocols/Makefile.am -text svneol=native#application/octet-stream MAC/GCF/Protocols/bootstrap -text svneol=native#application/octet-stream MAC/GCF/Protocols/configure.in -text svneol=native#application/octet-stream diff --git a/MAC/GCF/LogSys/CLP/Makefile.am b/MAC/GCF/LogSys/CLP/Makefile.am new file mode 100644 index 0000000000000000000000000000000000000000..4700d27db8516bebe3857fa6007afdf29a489a38 --- /dev/null +++ b/MAC/GCF/LogSys/CLP/Makefile.am @@ -0,0 +1,3 @@ +SUBDIRS=src + +include $(lofar_sharedir)/Makefile.common diff --git a/MAC/GCF/LogSys/CLP/src/CLPMain.cc b/MAC/GCF/LogSys/CLP/src/CLPMain.cc new file mode 100644 index 0000000000000000000000000000000000000000..c291440d75c53d4f44684f36dffd52aaa830526c --- /dev/null +++ b/MAC/GCF/LogSys/CLP/src/CLPMain.cc @@ -0,0 +1,39 @@ +//# CLPMain.cc: +//# +//# Copyright (C) 2002-2003 +//# ASTRON (Netherlands Foundation for Research in Astronomy) +//# P.O.Box 2, 7990 AA Dwingeloo, The Netherlands, seg@astron.nl +//# +//# This program is free software; you can redistribute it and/or modify +//# it under the terms of the GNU General Public License as published by +//# the Free Software Foundation; either version 2 of the License, or +//# (at your option) any later version. +//# +//# This program is distributed in the hope that it will be useful, +//# but WITHOUT ANY WARRANTY; without even the implied warranty of +//# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +//# GNU General Public License for more details. +//# +//# You should have received a copy of the GNU General Public License +//# along with this program; if not, write to the Free Software +//# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +//# +//# $Id$ + +#include <CodeLoggingProcessor.h> +#include <GCF/TM/GCF_Control.h> + +using namespace LOFAR::GCF; + +int main(int argC, char *argV[]) +{ + TM::GCFTask::init(argC, argV); + + LogSys::CodeLoggingProcessor clp; + + clp.start(); // make initial transition + + TM::GCFTask::run(); + + return 0; +} diff --git a/MAC/GCF/LogSys/CLP/src/CodeLoggingProcessor.cc b/MAC/GCF/LogSys/CLP/src/CodeLoggingProcessor.cc new file mode 100644 index 0000000000000000000000000000000000000000..b8cc6522375be337f234f93cb27120384df8d94c --- /dev/null +++ b/MAC/GCF/LogSys/CLP/src/CodeLoggingProcessor.cc @@ -0,0 +1,252 @@ +//# CodeLoggingProcessor.cc: +//# +//# Copyright (C) 2002-2003 +//# ASTRON (Netherlands Foundation for Research in Astronomy) +//# P.O.Box 2, 7990 AA Dwingeloo, The Netherlands, seg@astron.nl +//# +//# This program is free software; you can redistribute it and/or modify +//# it under the terms of the GNU General Public License as published by +//# the Free Software Foundation; either version 2 of the License, or +//# (at your option) any later version. +//# +//# This program is distributed in the hope that it will be useful, +//# but WITHOUT ANY WARRANTY; without even the implied warranty of +//# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +//# GNU General Public License for more details. +//# +//# You should have received a copy of the GNU General Public License +//# along with this program; if not, write to the Free Software +//# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +//# +//# $Id$ + +#include "CodeLoggingProcessor.h" +#include <log4cplus/helpers/socketbuffer.h> +#include <log4cplus/socketappender.h> +#include <GCF/LogSys/GCF_KeyValueLogger.h> +#include <GCF/GCF_PVString.h> +#include <GCF/GCF_PVChar.h> +#include <GCF/Utils.h> +#include <Common/StringUtil.h> + +using namespace log4cplus; +using namespace log4cplus::helpers; +namespace LOFAR +{ + namespace GCF + { +using namespace Common; +using namespace TM; + namespace LogSys + { + +CodeLoggingProcessor::CodeLoggingProcessor() : + GCFTask((State)&CodeLoggingProcessor::initial, "GCF-CLPD") +{ + // initialize the port + _clpPortProvider.init(*this, "server", GCFPortInterface::MSPP, 0, true); +} + +GCFEvent::TResult CodeLoggingProcessor::initial(GCFEvent& e, GCFPortInterface& p) +{ + GCFEvent::TResult status = GCFEvent::HANDLED; + switch (e.signal) + { + case F_INIT: + break; + + case F_ENTRY: + case F_TIMER: + if (!_clpPortProvider.isConnected()) + { + _clpPortProvider.open(); + } + break; + + case F_CONNECTED: + TRAN(CodeLoggingProcessor::operational); + break; + + case F_DISCONNECTED: + p.setTimer(1.0); // try again after 1 second + break; + + default: + status = GCFEvent::NOT_HANDLED; + break; + } + + return status; +} + +GCFEvent::TResult CodeLoggingProcessor::operational(GCFEvent& e, GCFPortInterface& p) +{ + GCFEvent::TResult status = GCFEvent::HANDLED; + static unsigned long garbageTimerID = 0; + + switch (e.signal) + { + case F_DISCONNECTED: + DBGFAILWHEN(&_clpPortProvider == &p && "CLP port provider may not be disconnected."); + LOG_INFO("Connection lost to a LofarLogger client."); + p.close(); + break; + + case F_TIMER: + { + // cleanup the garbage of closed ports to master clients + GCFPortInterface* pPort; + for (TClients::iterator iter = _clientsGarbage.begin(); + iter != _clientsGarbage.end(); ++iter) + { + pPort = *iter; + delete pPort; + } + _clientsGarbage.clear(); + break; + } + case F_CLOSED: + DBGFAILWHEN(&_clpPortProvider == &p); + _clients.erase(&p); + _clientsGarbage.push_back(&p); + break; + + case F_CONNECTED: + DBGFAILWHEN(&_clpPortProvider == &p); + break; + + case F_ACCEPT_REQ: + { + LOG_INFO("New LofarLogger client accepted!"); + GCFTCPPort* pNewCLPPort = new GCFTCPPort(); + assert(pNewCLPPort); + pNewCLPPort->init(*this, "clp-client", GCFPortInterface::SPP, 0, true); + _clpPortProvider.accept(*pNewCLPPort); + break; + } + case F_ENTRY: + garbageTimerID = _clpPortProvider.setTimer(1.0, 5.0); + break; + + case F_DATAIN: + { + // extract the incomming data to a Logger event object + SocketBuffer msgSizeBuffer(sizeof(unsigned int)); + if(!readFromPortData(p, msgSizeBuffer)) break; + + unsigned int msgSize = msgSizeBuffer.readInt(); + + SocketBuffer buffer(msgSize); + if(!readFromPortData(p, buffer)) break; + + spi::InternalLoggingEvent event = readFromBuffer(buffer); + + // prepare conversions + TLoggerClients::iterator iter = _clients.find(&p); + vector<string> key; + if (iter == _clients.end()) + { + bool startSequenceFound(false); + if (event.getLogLevel() == INFO_LOG_LEVEL) + { + string scope = event.getMessage(); + + if (scope.find("MACProcessScope:") == 0) + { + scope.erase(0, sizeof("MACProcessScope:")); + ltrim(scope); + rtrim(scope); + if (Utils::isValidPropName(scope.c_str())) + { + // context (can) contain '.' (dots) (KeyValue TreeDB notation) + key.push_back(scope); + + // '.' must be converted to the '_' in case of DP names + string::size_type dotSepPos; + while ((dotSepPos = scope.find('.')) < string::npos) + { + scope[dotSepPos] = '_'; + } + key.push_back(formatString("%s.logmsg", scope.c_str())); + _clients[&p] = key; + startSequenceFound = true; + // this start sequence message not needed to be logged + break; + } + } + } + if (!startSequenceFound) + { + // skip all incomming logger events + break; + } + } + else + { + key = iter->second; + } + + string file = event.getFile(); + string::size_type sepPos = file.rfind("/"); + if (sepPos < string::npos) + { + file.erase(0, sepPos + 1); + } + + string msg(formatString("%s|%s|%s|%s:%d", + getLogLevelManager().toString(event.getLogLevel()).c_str(), + event.getLoggerName().c_str(), + event.getMessage().c_str(), + file.c_str(), + event.getLine())); + + // convert the logger event to the key value + + GCFPVString value(msg); + + LOG_DEBUG(formatString( + "Msg: %s", + msg.c_str())); + + // timestamp conversion + timeval kvlTimestamp; + Time l4pTimestamp(event.getTimestamp()); + kvlTimestamp.tv_sec = l4pTimestamp.sec(); + kvlTimestamp.tv_usec = l4pTimestamp.usec(); + + // log! + LOG_KEYVALUE(key[0], value, KVL_ORIGIN_MAC, kvlTimestamp); + + // convert logger event to DP log msg + string plMsg = event.getTimestamp().getFormattedTime("%d-%m-%y %H:%M:%S.%q") + "|" + msg; + + GCFPVString plValue(plMsg); + _propertyProxy.setPropValue(key[1], plValue); + break; + } + default: + status = GCFEvent::NOT_HANDLED; + break; + } + + return status; +} + +bool CodeLoggingProcessor::readFromPortData(GCFPortInterface& port, SocketBuffer& buf) +{ + size_t res, read = 0; + do + { + res = port.recv(buf.getBuffer() + read, buf.getMaxSize() - read); + if ( res <= 0 ) + break; + + read += res; + } while ( read < buf.getMaxSize() ); + + return (read == buf.getMaxSize()); +} + + } // namespace LogSys + } // namespace GCF +} // namespace LOFAR diff --git a/MAC/GCF/LogSys/CLP/src/CodeLoggingProcessor.conf.in b/MAC/GCF/LogSys/CLP/src/CodeLoggingProcessor.conf.in new file mode 100644 index 0000000000000000000000000000000000000000..bfcbb25dc49d4b3995b476ae2ab39c35db1d3c9f --- /dev/null +++ b/MAC/GCF/LogSys/CLP/src/CodeLoggingProcessor.conf.in @@ -0,0 +1,3 @@ +mac.ns.GCF-CLPD.server.type=TCP +mac.ns.GCF-CLPD.server.port=25003 +mac.ns.GCF-CLPD.server.host=sun diff --git a/MAC/GCF/LogSys/CLP/src/CodeLoggingProcessor.h b/MAC/GCF/LogSys/CLP/src/CodeLoggingProcessor.h new file mode 100644 index 0000000000000000000000000000000000000000..6b8e71f09c4bc0d8ed0ce8cd207e0fdc394c6a26 --- /dev/null +++ b/MAC/GCF/LogSys/CLP/src/CodeLoggingProcessor.h @@ -0,0 +1,77 @@ +//# CodeLoggingProcessor.h: +//# +//# Copyright (C) 2002-2003 +//# ASTRON (Netherlands Foundation for Research in Astronomy) +//# P.O.Box 2, 7990 AA Dwingeloo, The Netherlands, seg@astron.nl +//# +//# This program is free software; you can redistribute it and/or modify +//# it under the terms of the GNU General Public License as published by +//# the Free Software Foundation; either version 2 of the License, or +//# (at your option) any later version. +//# +//# This program is distributed in the hope that it will be useful, +//# but WITHOUT ANY WARRANTY; without even the implied warranty of +//# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +//# GNU General Public License for more details. +//# +//# You should have received a copy of the GNU General Public License +//# along with this program; if not, write to the Free Software +//# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +//# +//# $Id$ + +#ifndef CODELOGGINGPROCESSOR_H +#define CODELOGGINGPROCESSOR_H + +#include <GCF/TM/GCF_Task.h> +#include <GCF/TM/GCF_Port.h> +#include <GCF/TM/GCF_TCPPort.h> +#include <PropertyProxy.h> + +namespace log4cplus +{ + namespace helpers + { +class SocketBuffer; + } +} +namespace LOFAR +{ + namespace GCF + { + namespace LogSys + { + +/** +*/ + +class CodeLoggingProcessor : public TM::GCFTask +{ + public: + CodeLoggingProcessor (); + virtual ~CodeLoggingProcessor () {} + + public: // member functions + + private: // state methods + TM::GCFEvent::TResult initial (TM::GCFEvent& e, TM::GCFPortInterface& p); + TM::GCFEvent::TResult operational (TM::GCFEvent& e, TM::GCFPortInterface& p); + + private: // helper methods + bool readFromPortData(TM::GCFPortInterface& port, log4cplus::helpers::SocketBuffer& buf); + + private: // data members + TM::GCFTCPPort _clpPortProvider; + typedef map<TM::GCFPortInterface*, vector<string> /*process context*/> TLoggerClients; + TLoggerClients _clients; + + private: // admin members + typedef list<TM::GCFPortInterface*> TClients; + TClients _clientsGarbage; + PropertyProxy _propertyProxy; +}; + } // namespace LogSys + } // namespace GCF +} // namespace LOFAR + +#endif diff --git a/MAC/GCF/LogSys/CLP/src/CodeLoggingProcessor.log_prop.in b/MAC/GCF/LogSys/CLP/src/CodeLoggingProcessor.log_prop.in new file mode 100644 index 0000000000000000000000000000000000000000..95af765a33022c655b5d9bd24c74828d92a0c8e2 --- /dev/null +++ b/MAC/GCF/LogSys/CLP/src/CodeLoggingProcessor.log_prop.in @@ -0,0 +1,15 @@ + +log4cplus.rootLogger=INFO, MACSTDERR +log4cplus.additivity.ASTRON=FALSE + +log4cplus.appender.STDOUT=log4cplus::ConsoleAppender +log4cplus.appender.STDOUT.layout=log4cplus::PatternLayout +log4cplus.appender.STDOUT.layout.ConversionPattern=%D{%d-%m-%y %H:%M:%S} %-5p %c{3} - %m [%.25l]%n +log4cplus.appender.MACSTDERR=log4cplus::ConsoleAppender +log4cplus.appender.MACSTDERR.layout=log4cplus::PatternLayout +log4cplus.appender.MACSTDERR.layout.ConversionPattern=%D{%d-%m %H:%M:%S.%q} %-5p %c{4} - %m [%.25l]%n +log4cplus.appender.MACSTDERR.logToStdErr=true + +log4cplus.additivity.MAC=FALSE +log4cplus.logger.MAC=DEBUG, MACSTDERR +log4cplus.logger.TRC=TRACE8 \ No newline at end of file diff --git a/MAC/GCF/LogSys/CLP/src/Makefile.am b/MAC/GCF/LogSys/CLP/src/Makefile.am new file mode 100644 index 0000000000000000000000000000000000000000..f6fb724e6644260d30111cd4853ec2cf65bc5954 --- /dev/null +++ b/MAC/GCF/LogSys/CLP/src/Makefile.am @@ -0,0 +1,42 @@ +INSTALL=/usr/bin/install -C + +pkgincludedir = $(includedir)/GCF/LogSys +pkginclude_HEADERS = + +DOCHDRS = $(pkginclude_HEADERS) \ + CodeLoggingProcessor.h \ + PropertyProxy.h + +noinst_LTLIBRARIES = libclp.la + +libclp_la_SOURCES = $(DOCHDRS) \ + CodeLoggingProcessor.cc \ + PropertyProxy.cc + +libclp_la_LIBADD = +libclp_la_CPPFLAGS= -DLOFARLOGGER_SUBPACKAGE=\"CLP\" + + +bin_PROGRAMS = CodeLoggingProcessor + +CodeLoggingProcessor_SOURCES = CLPMain.cc +CodeLoggingProcessor_LDADD = libclp.la $(LOFAR_DEPEND) \ + $(top_builddir)/KVLogSys/src/libgcfkvlc.la +CodeLoggingProcessor_DEPENDENCIES = libclp.la $(LOFAR_DEPEND) \ + $(top_builddir)/KVLogSys/src/libgcfkvlc.la +CodeLoggingProcessor_CPPFLAGS = -DLOFARLOGGER_SUBPACKAGE=\"CLP\" \ + -I$(top_srcdir)/include + +configfilesdir=$(bindir) +configfiles_DATA= \ + CodeLoggingProcessor.conf \ + CodeLoggingProcessor.log_prop + +%.conf: %.conf.in + cp $< $@ + +%.log_prop: %.log_prop.in + cp $< $@ + +include $(lofar_sharedir)/Makefile.common + diff --git a/MAC/GCF/LogSys/CLP/src/PropertyProxy.cc b/MAC/GCF/LogSys/CLP/src/PropertyProxy.cc new file mode 100644 index 0000000000000000000000000000000000000000..d392d31ed5bfa08ac3dc4e52eb3ad2316475a1b9 --- /dev/null +++ b/MAC/GCF/LogSys/CLP/src/PropertyProxy.cc @@ -0,0 +1,34 @@ +//# PropertyProxy.cc: +//# +//# Copyright (C) 2002-2003 +//# ASTRON (Netherlands Foundation for Research in Astronomy) +//# P.O.Box 2, 7990 AA Dwingeloo, The Netherlands, seg@astron.nl +//# +//# This program is free software; you can redistribute it and/or modify +//# it under the terms of the GNU General Public License as published by +//# the Free Software Foundation; either version 2 of the License, or +//# (at your option) any later version. +//# +//# This program is distributed in the hope that it will be useful, +//# but WITHOUT ANY WARRANTY; without even the implied warranty of +//# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +//# GNU General Public License for more details. +//# +//# You should have received a copy of the GNU General Public License +//# along with this program; if not, write to the Free Software +//# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +//# +//# $Id$ + +#include "PropertyProxy.h" + +namespace LOFAR +{ + namespace GCF + { + namespace LogSys + { + + } // namespace LogSys + } // namespace GCF +} // namespace LOFAR diff --git a/MAC/GCF/LogSys/CLP/src/PropertyProxy.h b/MAC/GCF/LogSys/CLP/src/PropertyProxy.h new file mode 100644 index 0000000000000000000000000000000000000000..40b49a050cf632466176cf75911e7d34261067ae --- /dev/null +++ b/MAC/GCF/LogSys/CLP/src/PropertyProxy.h @@ -0,0 +1,54 @@ +//# PropertyProxy.h: +//# +//# Copyright (C) 2002-2003 +//# ASTRON (Netherlands Foundation for Research in Astronomy) +//# P.O.Box 2, 7990 AA Dwingeloo, The Netherlands, seg@astron.nl +//# +//# This program is free software; you can redistribute it and/or modify +//# it under the terms of the GNU General Public License as published by +//# the Free Software Foundation; either version 2 of the License, or +//# (at your option) any later version. +//# +//# This program is distributed in the hope that it will be useful, +//# but WITHOUT ANY WARRANTY; without even the implied warranty of +//# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +//# GNU General Public License for more details. +//# +//# You should have received a copy of the GNU General Public License +//# along with this program; if not, write to the Free Software +//# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +//# +//# $Id$ + +#ifndef PROPERTYPROXY_H +#define PROPERTYPROXY_H + +#include <GCF/PAL/GCF_PropertyProxy.h> + +namespace LOFAR +{ + namespace GCF + { + namespace LogSys + { + +class PropertyProxy : public PAL::GCFPropertyProxy +{ + public: + PropertyProxy() {} + virtual ~PropertyProxy() {}; + + protected: + void propSubscribed(const string& /*propName*/) {} + void propSubscriptionLost(const string& /*propName*/) {} + void propUnsubscribed(const string& /*propName*/) {} + void propValueGet(const string& /*propName*/, const Common::GCFPValue& /*value*/) {} + void propValueChanged(const string& /*propName*/, const Common::GCFPValue& /*value*/) {} + void propValueSet(const string& /*propName*/) {} + + private: +}; + } // namespace LogSys + } // namespace GCF +} // namespace LOFAR +#endif diff --git a/MAC/GCF/LogSys/KVLogSys/Makefile.am b/MAC/GCF/LogSys/KVLogSys/Makefile.am new file mode 100644 index 0000000000000000000000000000000000000000..4700d27db8516bebe3857fa6007afdf29a489a38 --- /dev/null +++ b/MAC/GCF/LogSys/KVLogSys/Makefile.am @@ -0,0 +1,3 @@ +SUBDIRS=src + +include $(lofar_sharedir)/Makefile.common diff --git a/MAC/GCF/LogSys/KVLogSys/src/GCF_KeyValueLogger.cc b/MAC/GCF/LogSys/KVLogSys/src/GCF_KeyValueLogger.cc new file mode 100644 index 0000000000000000000000000000000000000000..fc5c1ebdb248af45a0868de049cb7e849bac11cb --- /dev/null +++ b/MAC/GCF/LogSys/KVLogSys/src/GCF_KeyValueLogger.cc @@ -0,0 +1,156 @@ +//# GCF_KeyValueLogger.cc: +//# +//# Copyright (C) 2002-2003 +//# ASTRON (Netherlands Foundation for Research in Astronomy) +//# P.O.Box 2, 7990 AA Dwingeloo, The Netherlands, seg@astron.nl +//# +//# This program is free software; you can redistribute it and/or modify +//# it under the terms of the GNU General Public License as published by +//# the Free Software Foundation; either version 2 of the License, or +//# (at your option) any later version. +//# +//# This program is distributed in the hope that it will be useful, +//# but WITHOUT ANY WARRANTY; without even the implied warranty of +//# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +//# GNU General Public License for more details. +//# +//# You should have received a copy of the GNU General Public License +//# along with this program; if not, write to the Free Software +//# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +//# +//# $Id$ + +#include <GCF/LogSys/GCF_KeyValueLogger.h> +#include <GCF/ParameterSet.h> +#include <KVL_Protocol.ph> +#include <KVLDefines.h> +#include <sys/time.h> +#include <time.h> + +namespace LOFAR +{ + namespace GCF + { +using namespace TM; +using namespace Common; + namespace LogSys + { + +GCFKeyValueLogger* GCFKeyValueLogger::_pInstance = 0; + +GCFKeyValueLogger* GCFKeyValueLogger::instance() +{ + if (!_pInstance) + { + _pInstance = new GCFKeyValueLogger(); + _pInstance->start(); + } + return _pInstance; +} + +GCFKeyValueLogger::GCFKeyValueLogger() : + GCFTask((State)&GCFKeyValueLogger::initial, KVL_CLIENT_TASK_NAME) +{ + // register the protocol for debugging purposes + registerProtocol(KVL_PROTOCOL, KVL_PROTOCOL_signalnames); + + // initialize the port + _kvlClientPort.init(*this, "client", GCFPortInterface::SAP, KVL_PROTOCOL); + ParameterSet::instance()->adoptFile("KeyValueLoggerDaemon.conf"); +} + +GCFEvent::TResult GCFKeyValueLogger::initial(GCFEvent& e, GCFPortInterface& /*p*/) +{ + GCFEvent::TResult status = GCFEvent::HANDLED; + switch (e.signal) + { + case F_INIT: + break; + + case F_ENTRY: + case F_TIMER: + _kvlClientPort.open(); + break; + + case F_CONNECTED: + TRAN(GCFKeyValueLogger::operational); + break; + + case F_DISCONNECTED: + _kvlClientPort.setTimer(1.0); // try again after 1 second + break; + + default: + status = GCFEvent::NOT_HANDLED; + break; + } + + return status; +} + +GCFEvent::TResult GCFKeyValueLogger::operational(GCFEvent& e, GCFPortInterface& p) +{ + GCFEvent::TResult status = GCFEvent::HANDLED; + + switch (e.signal) + { + case F_DISCONNECTED: + LOG_FATAL("Connection lost to KeyValue Logger deamon"); + p.close(); + break; + case F_CLOSED: + TRAN(GCFKeyValueLogger::initial); + break; + case F_ENTRY: + { + KVLUpdateEvent* pUpdateEvent; + for (TLogQueue::iterator iter = _logQueue.begin(); + iter != _logQueue.end(); ++iter) + { + pUpdateEvent = (KVLUpdateEvent*)*iter; + _kvlClientPort.send(*pUpdateEvent); + delete pUpdateEvent->value._pValue; + delete pUpdateEvent; + } + _logQueue.clear(); + break; + } + default: + status = GCFEvent::NOT_HANDLED; + break; + } + + return status; +} + +void GCFKeyValueLogger::logKeyValue(const string key, const GCFPValue& value, TKVLOrigin origin, const timeval& timestamp) +{ + KVLUpdateEvent* pIndication = new KVLUpdateEvent; + pIndication->key = key; + pIndication->value._pValue = &value; + pIndication->origin = origin; + pIndication->timestamp = timestamp; + + if (_kvlClientPort.isConnected()) + { + _kvlClientPort.send(*pIndication); + delete pIndication; + } + else + { + pIndication->value._pValue = value.clone(); + _logQueue.push_back(pIndication); + } +} + +void GCFKeyValueLogger::logKeyValue(const string key, const GCFPValue& value, TKVLOrigin origin) +{ + timeval timestamp; + struct timezone timeZone; + gettimeofday(×tamp, &timeZone); // TODO: find out whether this is the utc time or not + + logKeyValue(key, value, origin, timestamp); +} + } // namespace LogSys + } // namespace GCF +} // namespace LOFAR diff --git a/MAC/GCF/LogSys/KVLogSys/src/KVLDMain.cc b/MAC/GCF/LogSys/KVLogSys/src/KVLDMain.cc new file mode 100644 index 0000000000000000000000000000000000000000..2f6a58b0f5c43c2b95e79d6f18a711990d687f90 --- /dev/null +++ b/MAC/GCF/LogSys/KVLogSys/src/KVLDMain.cc @@ -0,0 +1,39 @@ +//# KVLDMain.cc: +//# +//# Copyright (C) 2002-2003 +//# ASTRON (Netherlands Foundation for Research in Astronomy) +//# P.O.Box 2, 7990 AA Dwingeloo, The Netherlands, seg@astron.nl +//# +//# This program is free software; you can redistribute it and/or modify +//# it under the terms of the GNU General Public License as published by +//# the Free Software Foundation; either version 2 of the License, or +//# (at your option) any later version. +//# +//# This program is distributed in the hope that it will be useful, +//# but WITHOUT ANY WARRANTY; without even the implied warranty of +//# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +//# GNU General Public License for more details. +//# +//# You should have received a copy of the GNU General Public License +//# along with this program; if not, write to the Free Software +//# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +//# +//# $Id$ + +#include <KeyValueLoggerDaemon.h> +#include <GCF/TM/GCF_Control.h> + +using namespace LOFAR::GCF; + +int main(int argC, char *argV[]) +{ + TM::GCFTask::init(argC, argV); + + LogSys::KeyValueLoggerDaemon daemon; + + daemon.start(); // make initial transition + + TM::GCFTask::run(); + + return 0; +} diff --git a/MAC/GCF/LogSys/KVLogSys/src/KVLDefines.h b/MAC/GCF/LogSys/KVLogSys/src/KVLDefines.h new file mode 100644 index 0000000000000000000000000000000000000000..df751ad84a4fe928102c098b8cdede8d290ad274 --- /dev/null +++ b/MAC/GCF/LogSys/KVLogSys/src/KVLDefines.h @@ -0,0 +1,50 @@ +//# KVDefines.h: preprocessor definitions of various constants +//# +//# Copyright (C) 2002-2003 +//# ASTRON (Netherlands Foundation for Research in Astronomy) +//# P.O.Box 2, 7990 AA Dwingeloo, The Netherlands, seg@astron.nl +//# +//# This program is free software; you can redistribute it and/or modify +//# it under the terms of the GNU General Public License as published by +//# the Free Software Foundation; either version 2 of the License, or +//# (at your option) any later version. +//# +//# This program is distributed in the hope that it will be useful, +//# but WITHOUT ANY WARRANTY; without even the implied warranty of +//# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +//# GNU General Public License for more details. +//# +//# You should have received a copy of the GNU General Public License +//# along with this program; if not, write to the Free Software +//# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +//# +//# $Id$ + +#ifndef KVDEFINES_H +#define KVDEFINES_H + +#include <GCF/GCF_Defines.h> + + +namespace LOFAR +{ + namespace GCF + { + namespace LogSys + { + +#define MAX_LOG_BUFF_SIZE 1400 +#define MAX_NR_OF_UPDATES 250 +#define MAX_NR_OF_RETRY_MSG 10 +#define CONNECTION_TIMEOUT 3600.0 // == 1 hour + +const string KVL_CLIENT_TASK_NAME("GCF-KVLC"); +const string KVL_DAEMON_TASK_NAME("GCF-KVLD"); +const string KVL_MASTER_TASK_NAME("GCF-KVLM"); + + + } // namespace PAL + } // namespace GCF +} // namespace LOFAR + +#endif diff --git a/MAC/GCF/LogSys/KVLogSys/src/KVLMMain.cc b/MAC/GCF/LogSys/KVLogSys/src/KVLMMain.cc new file mode 100644 index 0000000000000000000000000000000000000000..c492a603593e65717806130c107097c4cbd6700f --- /dev/null +++ b/MAC/GCF/LogSys/KVLogSys/src/KVLMMain.cc @@ -0,0 +1,39 @@ +//# KVLMMain.cc: +//# +//# Copyright (C) 2002-2003 +//# ASTRON (Netherlands Foundation for Research in Astronomy) +//# P.O.Box 2, 7990 AA Dwingeloo, The Netherlands, seg@astron.nl +//# +//# This program is free software; you can redistribute it and/or modify +//# it under the terms of the GNU General Public License as published by +//# the Free Software Foundation; either version 2 of the License, or +//# (at your option) any later version. +//# +//# This program is distributed in the hope that it will be useful, +//# but WITHOUT ANY WARRANTY; without even the implied warranty of +//# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +//# GNU General Public License for more details. +//# +//# You should have received a copy of the GNU General Public License +//# along with this program; if not, write to the Free Software +//# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +//# +//# $Id$ + +#include <KeyValueLoggerMaster.h> +#include <GCF/TM/GCF_Control.h> + +using namespace LOFAR::GCF; + +int main(int argC, char *argV[]) +{ + TM::GCFTask::init(argC, argV); + + LogSys::KeyValueLoggerMaster master; + + master.start(); // make initial transition + + TM::GCFTask::run(); + + return 0; +} diff --git a/MAC/GCF/LogSys/KVLogSys/src/KVLUtils.cc b/MAC/GCF/LogSys/KVLogSys/src/KVLUtils.cc new file mode 100644 index 0000000000000000000000000000000000000000..d014dc4cb428304b6212c59824fdfafee0355132 --- /dev/null +++ b/MAC/GCF/LogSys/KVLogSys/src/KVLUtils.cc @@ -0,0 +1,72 @@ +//# KVLUtils.cc: +//# +//# Copyright (C) 2002-2003 +//# ASTRON (Netherlands Foundation for Research in Astronomy) +//# P.O.Box 2, 7990 AA Dwingeloo, The Netherlands, seg@astron.nl +//# +//# This program is free software; you can redistribute it and/or modify +//# it under the terms of the GNU General Public License as published by +//# the Free Software Foundation; either version 2 of the License, or +//# (at your option) any later version. +//# +//# This program is distributed in the hope that it will be useful, +//# but WITHOUT ANY WARRANTY; without even the implied warranty of +//# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +//# GNU General Public License for more details. +//# +//# You should have received a copy of the GNU General Public License +//# along with this program; if not, write to the Free Software +//# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +//# +//# $Id$ + +#include "KVLUtils.h" +#include <GCF/ParameterSet.h> +#include <KVLDefines.h> +#include <sys/time.h> +#include <time.h> + +namespace LOFAR +{ + namespace GCF + { +using namespace Common; + namespace LogSys + { + +Value::~Value() +{ + if (_unpacked) delete _pValue; +} + +unsigned int Value::pack(char* buffer) +{ + assert(_pValue); + return _pValue->pack(buffer); +} + +unsigned int Value::unpack(char* buffer) +{ + assert(!_pValue); + _unpacked = true; + _pValue = GCFPValue::unpackValue(buffer); + return _pValue->getSize(); +} + +unsigned int Value::getSize() +{ + assert(_pValue); + return _pValue->getSize(); +} + +unsigned int LoggingCollection::unpack(char* buffer) +{ + GCFPValue* pValue(GCFPValue::unpackValue(buffer)); + assert(pValue); + buf.copy(*pValue); + delete pValue; + return buf.getSize(); +} + } // namespace LogSys + } // namespace GCF +} // namespace LOFAR diff --git a/MAC/GCF/LogSys/KVLogSys/src/KVLUtils.h b/MAC/GCF/LogSys/KVLogSys/src/KVLUtils.h new file mode 100644 index 0000000000000000000000000000000000000000..4a097b48608f408b5d201b2bedbbd9491b2a8192 --- /dev/null +++ b/MAC/GCF/LogSys/KVLogSys/src/KVLUtils.h @@ -0,0 +1,83 @@ +//# KVLDefines.h: +//# +//# Copyright (C) 2002-2003 +//# ASTRON (Netherlands Foundation for Research in Astronomy) +//# P.O.Box 2, 7990 AA Dwingeloo, The Netherlands, seg@astron.nl +//# +//# This program is free software; you can redistribute it and/or modify +//# it under the terms of the GNU General Public License as published by +//# the Free Software Foundation; either version 2 of the License, or +//# (at your option) any later version. +//# +//# This program is distributed in the hope that it will be useful, +//# but WITHOUT ANY WARRANTY; without even the implied warranty of +//# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +//# GNU General Public License for more details. +//# +//# You should have received a copy of the GNU General Public License +//# along with this program; if not, write to the Free Software +//# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +//# +//# $Id$ + +#ifndef KVLUTILS_H +#define KVLUTILS_H + +#include <GCF/TM/GCF_Event.h> +#include <GCF/GCF_PVBlob.h> + +namespace LOFAR +{ + namespace GCF + { + namespace LogSys + { + +/** +*/ + +class Value : public TM::GCFTransportable +{ + public: + Value() : _pValue(0), _unpacked(false) {}; + + virtual ~Value(); + + unsigned int pack(char* buffer); + unsigned int unpack(char* buffer); + unsigned int getSize(); + + const Common::GCFPValue* _pValue; + + private: + bool _unpacked; +}; + +class LoggingCollection : public TM::GCFTransportable +{ + public: + LoggingCollection() {}; + + virtual ~LoggingCollection() {}; + + unsigned int pack(char* buffer); + unsigned int unpack(char* buffer); + unsigned int getSize(); + + Common::GCFPVBlob buf; +}; + +inline unsigned int LoggingCollection::pack(char* buffer) +{ + return buf.pack(buffer); +} + +inline unsigned int LoggingCollection::getSize() +{ + return buf.getSize(); +} + } // namespace LogSys + } // namespace GCF +} // namespace LOFAR + +#endif diff --git a/MAC/GCF/LogSys/KVLogSys/src/KVL_Protocol.prot b/MAC/GCF/LogSys/KVLogSys/src/KVL_Protocol.prot new file mode 100644 index 0000000000000000000000000000000000000000..95fe1fbbd8983e04b9c97baa80a25d90c0df6a1b --- /dev/null +++ b/MAC/GCF/LogSys/KVLogSys/src/KVL_Protocol.prot @@ -0,0 +1,109 @@ +// +// Protocol definition for the KVL system +// +autogen definitions protocol; + +description = "Protocol for the KVL system"; +prefix = "KVL"; // for the signal names +id = "(LOFAR::GCF::TM::F_GCF_PROTOCOL + 4)"; + +include = '<GCF/GCF_Defines.h>'; +include = '<KVLUtils.h>'; + +prelude = << PRELUDE_END + +PRELUDE_END; +// +// An "event" has a "signal" and a "dir" (direction) +// and zero or more "param"s. +// "dir" can be one of "IN" or "OUT". +// A "param" has a "name" and a "type". +// +event = { + signal = UPDATE; + dir = IN; + param = { + name = "key"; + type = "string"; + }; + param = { + name = "value"; + type = "LOFAR::GCF::LogSys::Value"; + userdefined; + }; + param = { + name = "origin"; + type = "LOFAR::GCF::Common::TKVLOrigin"; + }; + param = { + name = "timestamp"; + type = "timeval"; + }; +}; + +event = { + signal = UPDATES; + dir = IN; + param = { + name = "seqNr"; + type = "uint16"; + }; + param = { + name = "daemonID"; + type = "uint8"; + }; + param = { + name = "nrOfUpdates"; + type = "uint16"; + }; + param = { + name = "updates"; + type = "LOFAR::GCF::LogSys::LoggingCollection"; + userdefined; + }; +}; + +event = { + signal = ANSWER; + dir = OUT; + param = { + name = "seqNr"; + type = "uint16"; + }; +}; + +event = { + signal = REGISTER; + dir = IN; + param = { + name = "curID"; + type = "uint8"; + }; + param = { + name = "firstSeqNr"; + type = "uint16"; + }; +}; + +event = { + signal = REGISTERED; + dir = OUT; + param = { + name = "ID"; + type = "uint8"; + }; + param = { + name = "curSeqNr"; + type = "uint16"; + }; +}; + +event = { + signal = UNREGISTER; + dir = IN; + param = { + name = "curID"; + type = "uint8"; + }; +}; + diff --git a/MAC/GCF/LogSys/KVLogSys/src/KeyValueLoggerDaemon.cc b/MAC/GCF/LogSys/KVLogSys/src/KeyValueLoggerDaemon.cc new file mode 100644 index 0000000000000000000000000000000000000000..1fcb86e1378814381d7451e5de3007563ee5254d --- /dev/null +++ b/MAC/GCF/LogSys/KVLogSys/src/KeyValueLoggerDaemon.cc @@ -0,0 +1,335 @@ +//# KeyValueLoggerDaemon.cc: +//# +//# Copyright (C) 2002-2003 +//# ASTRON (Netherlands Foundation for Research in Astronomy) +//# P.O.Box 2, 7990 AA Dwingeloo, The Netherlands, seg@astron.nl +//# +//# This program is free software; you can redistribute it and/or modify +//# it under the terms of the GNU General Public License as published by +//# the Free Software Foundation; either version 2 of the License, or +//# (at your option) any later version. +//# +//# This program is distributed in the hope that it will be useful, +//# but WITHOUT ANY WARRANTY; without even the implied warranty of +//# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +//# GNU General Public License for more details. +//# +//# You should have received a copy of the GNU General Public License +//# along with this program; if not, write to the Free Software +//# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +//# +//# $Id$ + +#include "KeyValueLoggerDaemon.h" +#include <GCF/ParameterSet.h> +#include <KVLDefines.h> +#include <sys/time.h> +#include <time.h> + +namespace LOFAR +{ +using TYPES::uint8; + namespace GCF + { +using namespace TM; + namespace LogSys + { + +KeyValueLoggerDaemon::KeyValueLoggerDaemon() : + GCFTask((State)&KeyValueLoggerDaemon::initial, KVL_DAEMON_TASK_NAME), + _nrOfBufferedUpdates(0), + _curLogBufSize(0), + _registerID(0), + _curSeqNr(0) +{ + // register the protocol for debugging purposes + registerProtocol(KVL_PROTOCOL, KVL_PROTOCOL_signalnames); + + // initialize the port + _kvlMasterClientPort.init(*this, "client", GCFPortInterface::SAP, KVL_PROTOCOL); + _kvlDaemonPortProvider.init(*this, "server", GCFPortInterface::MSPP, KVL_PROTOCOL); +} + +KeyValueLoggerDaemon::~KeyValueLoggerDaemon() +{ + KVLUnregisterEvent indication; + indication.curID = _registerID; + _kvlMasterClientPort.send(indication); +} + +GCFEvent::TResult KeyValueLoggerDaemon::initial(GCFEvent& e, GCFPortInterface& p) +{ + GCFEvent::TResult status = GCFEvent::HANDLED; + switch (e.signal) + { + case F_INIT: + break; + + case F_ENTRY: + case F_TIMER: + if (!_kvlDaemonPortProvider.isConnected()) + { + _kvlDaemonPortProvider.open(); + } + break; + + case F_CONNECTED: + TRAN(KeyValueLoggerDaemon::operational); + break; + + case F_DISCONNECTED: + p.setTimer(1.0); // try again after 1 second + break; + + default: + status = GCFEvent::NOT_HANDLED; + break; + } + + return status; +} + +GCFEvent::TResult KeyValueLoggerDaemon::operational(GCFEvent& e, GCFPortInterface& p) +{ + GCFEvent::TResult status = GCFEvent::HANDLED; + + static long hourTimerID = -1; + + switch (e.signal) + { + case F_DISCONNECTED: + DBGFAILWHEN(&_kvlDaemonPortProvider == &p && "Daemon port provider may not be disconnected."); + if (&_kvlMasterClientPort == &p) + { + LOG_WARN("Connection lost to KeyValue Logger master. Tries a reconnect!!!"); + _kvlMasterClientPort.cancelAllTimers(); + hourTimerID = _kvlMasterClientPort.setTimer(CONNECTION_TIMEOUT); + } + else + { + LOG_INFO("Connection lost to KeyValue Logger daemon client."); + } + p.close(); + break; + + case F_TIMER: + if (&_kvlDaemonPortProvider == &p) + { + GCFTimerEvent* pTimer = (GCFTimerEvent*)(&e); + if (hourTimerID == (long) pTimer->id) + { + // about 1 hour no connection: + // reset register ID, master also will release this number + // all buffered updates will lost + _registerID = 0; + _curSeqNr = 0; + hourTimerID = -2; // still no connection + } + else + { + // cleanup the garbage with closed ports to daemon clients + GCFPortInterface* pPort; + for (TClients::iterator iter = _clientsGarbage.begin(); + iter != _clientsGarbage.end(); ++iter) + { + pPort = *iter; + delete pPort; + } + _clientsGarbage.clear(); + } + } + else if (&_kvlMasterClientPort == &p) + { + if (!p.isConnected()) + { + // reconnect to master + p.open(); + } + else + { + if (_seqList.empty()) + { + if (_nrOfBufferedUpdates > 0) + { + // send current collected updates + sendLoggingBuffer(); + } + } + else if (_kvlMasterClientPort.isConnected()) + { + // resend max. 10 not answered messages + uint8 i = 0; + for (TSequenceList::iterator iter = _seqList.begin(); + iter != _seqList.end() && i < MAX_NR_OF_RETRY_MSG; ++iter) + { + if (iter->second->daemonID == 0) + { + iter->second->daemonID = _registerID; + } + _kvlMasterClientPort.send(*iter->second); + i++; + } + } + } + } + break; + + case F_CLOSED: + DBGFAILWHEN(&_kvlDaemonPortProvider == &p); + if (&_kvlMasterClientPort == &p) + { + _kvlMasterClientPort.setTimer(1.0); // try to reconnect again after 1 second; + } + else + { + _clients.remove(&p); + _clientsGarbage.push_back(&p); + } + break; + + case F_CONNECTED: + DBGFAILWHEN(&_kvlDaemonPortProvider == &p); + if (&_kvlMasterClientPort == &p) + { + _kvlDaemonPortProvider.cancelTimer(hourTimerID); + KVLRegisterEvent request; + request.curID = _registerID; + if (_seqList.size() > 0) + { + request.firstSeqNr = _seqList.begin()->first - 1; + } + else + { + request.firstSeqNr = _curSeqNr; + } + _kvlMasterClientPort.send(request); + hourTimerID = -1; + } + else + { + _clients.push_back(&p); + } + break; + + case F_ACCEPT_REQ: + { + LOG_INFO("New daemon client accepted!"); + GCFTCPPort* pNewDCPort = new GCFTCPPort(); + assert(pNewDCPort); + pNewDCPort->init(*this, "kvld-client", GCFPortInterface::SPP, KVL_PROTOCOL); + _kvlDaemonPortProvider.accept(*pNewDCPort); + break; + } + case F_ENTRY: + _kvlDaemonPortProvider.setTimer(1.0, 5.0); // garbage timer + if (!_kvlMasterClientPort.isConnected()) + { + _kvlMasterClientPort.open(); + } + break; + + case KVL_UPDATE: + { + if (hourTimerID == -2) + { + LOG_DEBUG("More than 1 hour no connection with the master, so dump all key value updates."); + break; + } + + if (_seqList.size() == 0xFFFF) + { + LOG_DEBUG("Cannot buffer more updates. Dump as long as the buffer decreases."); + break; + } + KVLUpdateEvent event(e); + + unsigned int neededSize; + void* buf = event.pack(neededSize); + // skip the signal field, not needed anymore + neededSize -= sizeof(e.signal); + char* packedEvent = (char*) buf; + packedEvent += sizeof(e.signal); + + if (_curLogBufSize + neededSize > MAX_LOG_BUFF_SIZE) + { + sendLoggingBuffer(); + } + + memcpy(_logBuf + _curLogBufSize, packedEvent, neededSize); + _curLogBufSize += neededSize; + + _nrOfBufferedUpdates++; + if (_nrOfBufferedUpdates == MAX_NR_OF_UPDATES) + { + sendLoggingBuffer(); + } + break; + } + case KVL_ANSWER: + { + KVLAnswerEvent answer(e); + TSequenceList::iterator iter = _seqList.find(answer.seqNr); + LOG_DEBUG(formatString( + "Message with nr. %d was successfully received by the master.", + answer.seqNr)); + + if (iter != _seqList.end()) + { + delete iter->second; + } + _seqList.erase(answer.seqNr); + break; + } + + case KVL_REGISTERED: + { + KVLRegisteredEvent response(e); + if (_registerID != response.ID) + { + LOG_DEBUG(formatString( + "Registered on master with nr. %d", + response.ID)); + } + _registerID = response.ID; + + for (uint16 i = 0; i < MAX_NR_OF_RETRY_MSG; i++) + { + _seqList.erase(response.curSeqNr - i); + } + _kvlMasterClientPort.setTimer(1.0, 1.0); // start the (re)send heartbeat + break; + } + default: + status = GCFEvent::NOT_HANDLED; + break; + } + + return status; +} + +void KeyValueLoggerDaemon::sendLoggingBuffer() +{ + _curSeqNr++; + + LOG_DEBUG(formatString( + "Message with nr. %d is prepared to send.", + _curSeqNr)); + + KVLUpdatesEvent* pUpdatesEvent = new KVLUpdatesEvent; + pUpdatesEvent->seqNr = _curSeqNr; + pUpdatesEvent->daemonID = _registerID; + pUpdatesEvent->nrOfUpdates = _nrOfBufferedUpdates; + pUpdatesEvent->updates.buf.setValue(_logBuf, _curLogBufSize, true); + + if (_kvlMasterClientPort.isConnected()) + { + _kvlMasterClientPort.send(*pUpdatesEvent); + } + _seqList.insert(_seqList.end(), std::make_pair(_curSeqNr, pUpdatesEvent)); + _curLogBufSize = 0; + _nrOfBufferedUpdates = 0; +} + + } // namespace LogSys + } // namespace GCF +} // namespace LOFAR diff --git a/MAC/GCF/LogSys/KVLogSys/src/KeyValueLoggerDaemon.h b/MAC/GCF/LogSys/KVLogSys/src/KeyValueLoggerDaemon.h new file mode 100644 index 0000000000000000000000000000000000000000..90b4e41d8cde0d5e8967bf5b676612253f16b781 --- /dev/null +++ b/MAC/GCF/LogSys/KVLogSys/src/KeyValueLoggerDaemon.h @@ -0,0 +1,77 @@ +//# KeyValueLoggerDaemon.h: +//# +//# Copyright (C) 2002-2003 +//# ASTRON (Netherlands Foundation for Research in Astronomy) +//# P.O.Box 2, 7990 AA Dwingeloo, The Netherlands, seg@astron.nl +//# +//# This program is free software; you can redistribute it and/or modify +//# it under the terms of the GNU General Public License as published by +//# the Free Software Foundation; either version 2 of the License, or +//# (at your option) any later version. +//# +//# This program is distributed in the hope that it will be useful, +//# but WITHOUT ANY WARRANTY; without even the implied warranty of +//# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +//# GNU General Public License for more details. +//# +//# You should have received a copy of the GNU General Public License +//# along with this program; if not, write to the Free Software +//# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +//# +//# $Id$ + +#ifndef KEYVALUELOGGERDAEMON_H +#define KEYVALUELOGGERDAEMON_H + +#include <GCF/TM/GCF_Task.h> +#include <GCF/TM/GCF_Port.h> +#include <GCF/TM/GCF_TCPPort.h> +#include <KVL_Protocol.ph> +#include <KVLDefines.h> + +namespace LOFAR +{ + namespace GCF + { + namespace LogSys + { + +/** +*/ + +class KeyValueLoggerDaemon : public TM::GCFTask +{ + public: + KeyValueLoggerDaemon (); + virtual ~KeyValueLoggerDaemon (); + + public: // member functions + + private: // state methods + TM::GCFEvent::TResult initial (TM::GCFEvent& e, TM::GCFPortInterface& p); + TM::GCFEvent::TResult operational (TM::GCFEvent& e, TM::GCFPortInterface& p); + + private: // helper methods + void sendLoggingBuffer(); + + private: // data members + TM::GCFTCPPort _kvlDaemonPortProvider; + TM::GCFPort _kvlMasterClientPort; + typedef list<TM::GCFPortInterface*> TClients; + TClients _clients; + + private: // admin members + typedef map<unsigned int /*seqnr */, KVLUpdatesEvent*> TSequenceList; + TSequenceList _seqList; + TClients _clientsGarbage; + unsigned char _logBuf[MAX_LOG_BUFF_SIZE]; + unsigned int _nrOfBufferedUpdates; + unsigned int _curLogBufSize; + uint8 _registerID; + uint16 _curSeqNr; +}; + } // namespace LogSys + } // namespace GCF +} // namespace LOFAR + +#endif diff --git a/MAC/GCF/LogSys/KVLogSys/src/KeyValueLoggerMaster.cc b/MAC/GCF/LogSys/KVLogSys/src/KeyValueLoggerMaster.cc new file mode 100644 index 0000000000000000000000000000000000000000..7acc785c93fea35dc9d4b973975c5b98953e7919 --- /dev/null +++ b/MAC/GCF/LogSys/KVLogSys/src/KeyValueLoggerMaster.cc @@ -0,0 +1,313 @@ +//# KeyValueLoggerMaster.cc: +//# +//# Copyright (C) 2002-2003 +//# ASTRON (Netherlands Foundation for Research in Astronomy) +//# P.O.Box 2, 7990 AA Dwingeloo, The Netherlands, seg@astron.nl +//# +//# This program is free software; you can redistribute it and/or modify +//# it under the terms of the GNU General Public License as published by +//# the Free Software Foundation; either version 2 of the License, or +//# (at your option) any later version. +//# +//# This program is distributed in the hope that it will be useful, +//# but WITHOUT ANY WARRANTY; without even the implied warranty of +//# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +//# GNU General Public License for more details. +//# +//# You should have received a copy of the GNU General Public License +//# along with this program; if not, write to the Free Software +//# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +//# +//# $Id$ + +#include "KeyValueLoggerMaster.h" +#include <GCF/ParameterSet.h> +#include <KVLDefines.h> +#include <sys/time.h> +#include <time.h> + +namespace LOFAR +{ + namespace GCF + { +using namespace TM; + namespace LogSys + { + +KeyValueLoggerMaster::KeyValueLoggerMaster() : + GCFTask((State)&KeyValueLoggerMaster::initial, KVL_MASTER_TASK_NAME) +{ + // register the protocol for debugging purposes + registerProtocol(KVL_PROTOCOL, KVL_PROTOCOL_signalnames); + + // initialize the port + _kvlMasterPortProvider.init(*this, "server", GCFPortInterface::MSPP, KVL_PROTOCOL); +} + +GCFEvent::TResult KeyValueLoggerMaster::initial(GCFEvent& e, GCFPortInterface& p) +{ + GCFEvent::TResult status = GCFEvent::HANDLED; + switch (e.signal) + { + case F_INIT: + break; + + case F_ENTRY: + case F_TIMER: + if (!_kvlMasterPortProvider.isConnected()) + { + _kvlMasterPortProvider.open(); + } + break; + + case F_CONNECTED: + TRAN(KeyValueLoggerMaster::operational); + break; + + case F_DISCONNECTED: + p.setTimer(1.0); // try again after 1 second + break; + + default: + status = GCFEvent::NOT_HANDLED; + break; + } + + return status; +} + +GCFEvent::TResult KeyValueLoggerMaster::operational(GCFEvent& e, GCFPortInterface& p) +{ + GCFEvent::TResult status = GCFEvent::HANDLED; + static unsigned long garbageTimerID = 0; + + switch (e.signal) + { + case F_DISCONNECTED: + DBGFAILWHEN(&_kvlMasterPortProvider == &p && "Master port provider may not be disconnected."); + LOG_INFO("Connection lost to a KeyValue Logger daemon client."); + p.close(); + break; + + case F_TIMER: + if (&_kvlMasterPortProvider == &p) + { + GCFTimerEvent* pTimer = (GCFTimerEvent*)(&e); + if (garbageTimerID == pTimer->id) + { + // cleanup the garbage of closed ports to master clients + GCFPortInterface* pPort; + for (TClients::iterator iter = _clientsGarbage.begin(); + iter != _clientsGarbage.end(); ++iter) + { + pPort = *iter; + delete pPort; + } + _clientsGarbage.clear(); + } + else + { + // erase the deamon client registration after one hour no connection + for (TRegisteredClients::iterator iter = _clients.begin(); + iter != _clients.end(); ++iter) + { + if ((iter->second.pPort == 0) && (iter->second.hourTimerID == pTimer->id)) + { + LOG_DEBUG(formatString( + "Hour timer %d for disconnected daemon %d is elapsed. Deletes the daemon client registration!", + iter->second.hourTimerID, + iter->first)); + _clients.erase(iter->first); + break; + } + } + } + } + break; + + case F_CLOSED: + DBGFAILWHEN(&_kvlMasterPortProvider == &p); + for (TRegisteredClients::iterator iter = _clients.begin(); + iter != _clients.end(); ++iter) + { + if (iter->second.pPort == &p) + { + iter->second.pPort = 0; + iter->second.hourTimerID = _kvlMasterPortProvider.setTimer(CONNECTION_TIMEOUT); + LOG_DEBUG(formatString( + "Hour timer %d for disconnected daemon %d is started.", + iter->second.hourTimerID, + iter->first)); + break; + } + } + _clientsGarbage.push_back(&p); + break; + + case F_CONNECTED: + DBGFAILWHEN(&_kvlMasterPortProvider == &p); + break; + + case F_ACCEPT_REQ: + { + LOG_INFO("New master client accepted!"); + GCFTCPPort* pNewMCPort = new GCFTCPPort(); + assert(pNewMCPort); + pNewMCPort->init(*this, "kvlm-client", GCFPortInterface::SPP, KVL_PROTOCOL); + _kvlMasterPortProvider.accept(*pNewMCPort); + break; + } + case F_ENTRY: + garbageTimerID = _kvlMasterPortProvider.setTimer(1.0, 5.0); + break; + + case KVL_UPDATES: + { + KVLUpdatesEvent inEvent(e); + TRegisteredClients::iterator iter = _clients.find(inEvent.daemonID); + + LOG_DEBUG(formatString( + "Daemon %d has new updates", + inEvent.daemonID)); + + DBGASSERT(iter != _clients.end()); + + LOG_DEBUG(formatString( + "^-Receives update collection with seqnr. %d.", + inEvent.seqNr, + iter->first)); + if (((iter->second.curSeqNr + 1) % 0xFFFF) == inEvent.seqNr) + { + KVLAnswerEvent outAnswer; + outAnswer.seqNr = inEvent.seqNr; + p.send(outAnswer); + LOG_DEBUG(formatString( + "^-Processing update collection with seqnr. %d.", + inEvent.seqNr, + iter->first)); + iter->second.curSeqNr = inEvent.seqNr; + + unsigned char* updatesData = inEvent.updates.buf.getValue(); + uint16 updatesDataLength = inEvent.updates.buf.getLen(); + GCFEvent rawEvent(KVL_UPDATE); + GCFEvent* fullUpdateEvent(0); + char* eventBuf(0); + + for (uint16 i = 0; i < inEvent.nrOfUpdates; i++) + { + // expects and reads the length field + DBGASSERT(updatesDataLength > sizeof(rawEvent.length)); + memcpy(&rawEvent.length, updatesData, sizeof(rawEvent.length)); + updatesDataLength -= sizeof(rawEvent.length); + updatesData += sizeof(rawEvent.length); + + // expects and reads the payload + DBGASSERT(rawEvent.length > 0); + DBGASSERT(rawEvent.length <= updatesDataLength); + eventBuf = new char[sizeof(rawEvent) + rawEvent.length]; + fullUpdateEvent = (GCFEvent*)eventBuf; + memcpy(eventBuf, &rawEvent, sizeof(rawEvent)); + + // read the payload right behind the just memcopied basic event structure + memcpy(eventBuf + sizeof(rawEvent), updatesData, rawEvent.length); + + KVLUpdateEvent updateEvent(*fullUpdateEvent); + + LOG_DEBUG(formatString( + "key: %s, unr: %d, udl: %d", + updateEvent.key.c_str(), + i, + updatesDataLength)); + + delete [] eventBuf; + updatesDataLength -= rawEvent.length; + updatesData += rawEvent.length; + } + } + else + { + LOG_DEBUG(formatString( + "^-Skip update collection with seqnr. %d!", + inEvent.seqNr, + iter->first)); + } + break; + } + case KVL_REGISTER: + { + KVLRegisterEvent request(e); + KVLRegisteredEvent response; + TRegisteredClients::iterator iter; + + if (request.curID == 0) + { + TClient client; + client.pPort = &p; + client.curSeqNr = 0; + uint8 newClientID = 0; + do + { + newClientID++; + iter = _clients.find(newClientID); + } + while (iter != _clients.end()); + + LOG_DEBUG(formatString( + "A (new) daemon is registered with ID %d", + newClientID)); + _clients[newClientID] = client; + response.ID = newClientID; + response.curSeqNr = 0; + } + else + { + LOG_DEBUG(formatString( + "A daemon is re-registered with ID %d", + request.curID)); + response.ID = request.curID; + iter = _clients.find(request.curID); + if (iter == _clients.end()) + { + TClient client; + client.pPort = &p; + client.curSeqNr = request.firstSeqNr; + client.hourTimerID = 0; + _clients[request.curID] = client; + response.curSeqNr = request.firstSeqNr; + } + else + { + DBGASSERT(iter->second.pPort == 0); + iter->second.pPort = &p; + _kvlMasterPortProvider.cancelTimer(iter->second.hourTimerID); + LOG_DEBUG(formatString( + "Cancel hour timer %d for daemon %d (if necessary!).", + iter->second.hourTimerID, + request.curID)); + iter->second.hourTimerID = 0; + response.curSeqNr = iter->second.curSeqNr; + } + } + p.send(response); + break; + } + case KVL_UNREGISTER: + { + KVLUnregisterEvent indication(e); + LOG_DEBUG(formatString( + "Daemon %d unregistered.", + indication.curID)); + _clients.erase(indication.curID); + break; + } + default: + status = GCFEvent::NOT_HANDLED; + break; + } + + return status; +} + + } // namespace LogSys + } // namespace GCF +} // namespace LOFAR diff --git a/MAC/GCF/LogSys/KVLogSys/src/KeyValueLoggerMaster.h b/MAC/GCF/LogSys/KVLogSys/src/KeyValueLoggerMaster.h new file mode 100644 index 0000000000000000000000000000000000000000..95c0b32f3d1e2f4d81a8f3caaae3887b6bcc8e2d --- /dev/null +++ b/MAC/GCF/LogSys/KVLogSys/src/KeyValueLoggerMaster.h @@ -0,0 +1,76 @@ +//# KeyValueLoggerMaster.h: +//# +//# Copyright (C) 2002-2003 +//# ASTRON (Netherlands Foundation for Research in Astronomy) +//# P.O.Box 2, 7990 AA Dwingeloo, The Netherlands, seg@astron.nl +//# +//# This program is free software; you can redistribute it and/or modify +//# it under the terms of the GNU General Public License as published by +//# the Free Software Foundation; either version 2 of the License, or +//# (at your option) any later version. +//# +//# This program is distributed in the hope that it will be useful, +//# but WITHOUT ANY WARRANTY; without even the implied warranty of +//# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +//# GNU General Public License for more details. +//# +//# You should have received a copy of the GNU General Public License +//# along with this program; if not, write to the Free Software +//# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +//# +//# $Id$ + +#ifndef KEYVALUELOGGERMASTER_H +#define KEYVALUELOGGERMASTER_H + +#include <GCF/TM/GCF_Task.h> +#include <GCF/TM/GCF_Port.h> +#include <GCF/TM/GCF_TCPPort.h> +#include <KVL_Protocol.ph> +#include <KVLDefines.h> + +namespace LOFAR +{ + namespace GCF + { + namespace LogSys + { + +/** +*/ + +class KeyValueLoggerMaster : public TM::GCFTask +{ + public: + KeyValueLoggerMaster (); + virtual ~KeyValueLoggerMaster () {} + + public: // member functions + + private: // state methods + TM::GCFEvent::TResult initial (TM::GCFEvent& e, TM::GCFPortInterface& p); + TM::GCFEvent::TResult operational (TM::GCFEvent& e, TM::GCFPortInterface& p); + + private: // helper methods + + private: // data members + TM::GCFTCPPort _kvlMasterPortProvider; + struct TClient + { + TM::GCFPortInterface* pPort; + unsigned long hourTimerID; + uint32 curSeqNr; + }; + + typedef map<uint8 /*clientID*/, TClient> TRegisteredClients; + TRegisteredClients _clients; + + private: // admin members + typedef list<TM::GCFPortInterface*> TClients; + TClients _clientsGarbage; +}; + } // namespace LogSys + } // namespace GCF +} // namespace LOFAR + +#endif diff --git a/MAC/GCF/LogSys/KVLogSys/src/KeyValueLoggerSys.conf.in b/MAC/GCF/LogSys/KVLogSys/src/KeyValueLoggerSys.conf.in new file mode 100644 index 0000000000000000000000000000000000000000..785e54fe2b1156fc3b14a95324b8f3a28f703454 --- /dev/null +++ b/MAC/GCF/LogSys/KVLogSys/src/KeyValueLoggerSys.conf.in @@ -0,0 +1,8 @@ +mac.ns.GCF-KVLM.server.type=TCP +mac.ns.GCF-KVLM.server.port=25001 +mac.ns.GCF-KVLM.server.host=sun +mac.top.GCF-KVLD.client.remoteservice=GCF-KVLM:server +mac.ns.GCF-KVLD.server.type=TCP +mac.ns.GCF-KVLD.server.port=25002 +mac.ns.GCF-KVLD.server.host=sun +mac.top.GCF-KVLC.client.remoteservice=GCF-KVLD:server \ No newline at end of file diff --git a/MAC/GCF/LogSys/KVLogSys/src/KeyValueLoggerSys.log_prop.in b/MAC/GCF/LogSys/KVLogSys/src/KeyValueLoggerSys.log_prop.in new file mode 100644 index 0000000000000000000000000000000000000000..95af765a33022c655b5d9bd24c74828d92a0c8e2 --- /dev/null +++ b/MAC/GCF/LogSys/KVLogSys/src/KeyValueLoggerSys.log_prop.in @@ -0,0 +1,15 @@ + +log4cplus.rootLogger=INFO, MACSTDERR +log4cplus.additivity.ASTRON=FALSE + +log4cplus.appender.STDOUT=log4cplus::ConsoleAppender +log4cplus.appender.STDOUT.layout=log4cplus::PatternLayout +log4cplus.appender.STDOUT.layout.ConversionPattern=%D{%d-%m-%y %H:%M:%S} %-5p %c{3} - %m [%.25l]%n +log4cplus.appender.MACSTDERR=log4cplus::ConsoleAppender +log4cplus.appender.MACSTDERR.layout=log4cplus::PatternLayout +log4cplus.appender.MACSTDERR.layout.ConversionPattern=%D{%d-%m %H:%M:%S.%q} %-5p %c{4} - %m [%.25l]%n +log4cplus.appender.MACSTDERR.logToStdErr=true + +log4cplus.additivity.MAC=FALSE +log4cplus.logger.MAC=DEBUG, MACSTDERR +log4cplus.logger.TRC=TRACE8 \ No newline at end of file diff --git a/MAC/GCF/LogSys/KVLogSys/src/Makefile.am b/MAC/GCF/LogSys/KVLogSys/src/Makefile.am new file mode 100644 index 0000000000000000000000000000000000000000..1b6b29536ee8dfd58f6627a75b57522e4a7f5afa --- /dev/null +++ b/MAC/GCF/LogSys/KVLogSys/src/Makefile.am @@ -0,0 +1,81 @@ +INSTALL=/usr/bin/install -C + +AUTOGEN = autogen +SUFFIXES = .ph + +%.ph: %.prot + $(AUTOGEN) --writable -L $(top_srcdir)/../../MACCommon/autogen $< + +pkgincludedir = $(includedir)/GCF/LogSys +pkginclude_HEADERS = \ + ../../include/GCF/LogSys/GCF_KeyValueLogger.h + +DOCHDRS = $(pkginclude_HEADERS) \ + KVDefines.h \ + KeyValueLoggerDaemon.h \ + KeyValueLoggerMaster.h \ + KVLUtils.h \ + KVL_Protocol.ph + +lib_LTLIBRARIES = libgcfkvlc.la + +libgcfkvlc_la_SOURCES= $(DOCHDRS) \ + GCF_KeyValueLogger.cc + +libgcfkvlc_la_LIBADD= libkvlprot.la +libgcfkvlc_la_DEPENDENCIES= libkvlprot.la $(LOFAR_DEPEND) +libgcfkvlc_la_CPPFLAGS= -I$(top_srcdir)/include \ + -DLOFARLOGGER_SUBPACKAGE=\"KVLC\" + +noinst_LTLIBRARIES = libkvlprot.la libkvld.la libkvlm.la + +libkvlprot_la_SOURCES= $(DOCHDRS) \ + KVL_Protocol.cc \ + KVLUtils.cc + +libkvld_la_SOURCES = $(DOCHDRS) \ + KeyValueLoggerDaemon.cc + +libkvld_la_LIBADD = libkvlprot.la +libkvld_la_CPPFLAGS= -DLOFARLOGGER_SUBPACKAGE=\"KVLD\" + +libkvlm_la_SOURCES = $(DOCHDRS) \ + KeyValueLoggerMaster.cc + +libkvlm_la_LIBADD = libkvlprot.la +libkvlm_la_CPPFLAGS= -DLOFARLOGGER_SUBPACKAGE=\"KVLM\" + +bin_PROGRAMS = KeyValueLoggerDaemon KeyValueLoggerMaster + +KeyValueLoggerDaemon_SOURCES = KVLDMain.cc +KeyValueLoggerDaemon_LDADD = libkvld.la $(LOFAR_DEPEND) +KeyValueLoggerDaemon_DEPENDENCIES = libkvld.la $(LOFAR_DEPEND) +KeyValueLoggerDaemon_CPPFLAGS = -DLOFARLOGGER_SUBPACKAGE=\"KVLD\" + +KeyValueLoggerMaster_SOURCES = KVLMMain.cc +KeyValueLoggerMaster_LDADD = libkvlm.la $(LOFAR_DEPEND) +KeyValueLoggerMaster_DEPENDENCIES = libkvlm.la $(LOFAR_DEPEND) +KeyValueLoggerMaster_CPPFLAGS = -DLOFARLOGGER_SUBPACKAGE=\"KVLM\" + +BUILT_SOURCES = \ + KVL_Protocol.ph + +EXTRA_DIST = \ + KVL_Protocol.ph + +configfilesdir=$(bindir) +configfiles_DATA= \ + KeyValueLoggerDaemon.conf \ + KeyValueLoggerMaster.conf \ + KeyValueLoggerDaemon.log_prop \ + KeyValueLoggerMaster.log_prop + + +%.conf: KeyValueLoggerSys.conf.in + cp $< $@ + +%.log_prop: KeyValueLoggerSys.log_prop.in + cp $< $@ + +include $(lofar_sharedir)/Makefile.common + diff --git a/MAC/GCF/LogSys/Makefile.am b/MAC/GCF/LogSys/Makefile.am new file mode 100644 index 0000000000000000000000000000000000000000..0de1a92916f6334f4d29499e932b14873427ab41 --- /dev/null +++ b/MAC/GCF/LogSys/Makefile.am @@ -0,0 +1,3 @@ +SUBDIRS=KVLogSys CLP + +include $(lofar_sharedir)/Makefile.common diff --git a/MAC/GCF/LogSys/bootstrap b/MAC/GCF/LogSys/bootstrap new file mode 100755 index 0000000000000000000000000000000000000000..06f18cde1dbfd6912ef7d927c4d35d25c7137a62 --- /dev/null +++ b/MAC/GCF/LogSys/bootstrap @@ -0,0 +1,3 @@ +#!/bin/sh + +../../../autoconf_share/bootstrap ../../../autoconf_share diff --git a/MAC/GCF/LogSys/configure.in b/MAC/GCF/LogSys/configure.in new file mode 100644 index 0000000000000000000000000000000000000000..ce410fd0dc502c3efc05a61ac6511425e993f8c1 --- /dev/null +++ b/MAC/GCF/LogSys/configure.in @@ -0,0 +1,60 @@ +dnl +dnl Process this file with autoconf to produce a configure script. +dnl +AC_INIT(include/GCF/LogSys/GCF_KeyValueLogger.h) +dnl AC_CONFIG_AUX_DIR(config) +dnl AM_CONFIG_HEADER(config/config.h) +AM_CONFIG_HEADER(config.h) +AM_INIT_AUTOMAKE(GCF/LogSys, 1.0) + +dnl Initialize for LOFAR (may set compilers) +lofar_INIT + +dnl Checks for programs. +AC_PROG_AWK +AC_PROG_YACC +AC_PROG_CC +AC_PROG_CXX +AM_PROG_LEX +AC_PROG_INSTALL +AC_PROG_LN_S +AC_DISABLE_SHARED +AC_PROG_LIBTOOL + +dnl Checks for libraries. + +dnl Checks for header files. +AC_HEADER_STDC +AC_CHECK_HEADERS(unistd.h) + +dnl Checks for typedefs, structures, and compiler characteristics. +AC_C_CONST +AC_TYPE_SIZE_T + +dnl Checks for library functions. +AC_FUNC_VPRINTF + +dnl +dnl Check for LOFAR specific things +dnl +lofar_DEBUG_OPTIMIZE +#lofar_QT +lofar_QATOOLS +lofar_LOG4CPLUS +lofar_DOCXX +lofar_PVSS +lofar_INTERNAL(LCS/Common, common, LCS-Common-2_1, 1, Common/LofarTypes.h,,) +lofar_INTERNAL(MAC/GCF/GCFCommon, gcfcommon, MAC-GCF-5_0, 1, GCF/GCF_Defines.h,,) +lofar_INTERNAL(MAC/GCF/TM, gcftm, MAC-GCF-5_0, 1, GCF/TM/GCF_Task.h,,) +lofar_INTERNAL(MAC/GCF/PAL, gcfpal, MAC-GCF-5_0, 1, GCF/PAL/GCF_PVSSInfo.h,,) + +dnl +dnl Output Makefiles +dnl +AC_OUTPUT( +KVLogSys/src/Makefile +KVLogSys/Makefile +CLP/src/Makefile +CLP/Makefile +Makefile +) diff --git a/MAC/GCF/LogSys/include/GCF/LogSys/GCF_KeyValueLogger.h b/MAC/GCF/LogSys/include/GCF/LogSys/GCF_KeyValueLogger.h new file mode 100644 index 0000000000000000000000000000000000000000..cfc4dcdc57a399470588f107c3c79350ed00bf36 --- /dev/null +++ b/MAC/GCF/LogSys/include/GCF/LogSys/GCF_KeyValueLogger.h @@ -0,0 +1,82 @@ +//# GCF_KeyValueLogger.h: singleton class; bridge between controller application +//# and KeyValueLoggerDaemon +//# +//# Copyright (C) 2002-2003 +//# ASTRON (Netherlands Foundation for Research in Astronomy) +//# P.O.Box 2, 7990 AA Dwingeloo, The Netherlands, seg@astron.nl +//# +//# This program is free software; you can redistribute it and/or modify +//# it under the terms of the GNU General Public License as published by +//# the Free Software Foundation; either version 2 of the License, or +//# (at your option) any later version. +//# +//# This program is distributed in the hope that it will be useful, +//# but WITHOUT ANY WARRANTY; without even the implied warranty of +//# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +//# GNU General Public License for more details. +//# +//# You should have received a copy of the GNU General Public License +//# along with this program; if not, write to the Free Software +//# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +//# +//# $Id$ + +#ifndef GCF_KEYVALUELOGGER_H +#define GCF_KEYVALUELOGGER_H + +#include <GCF/TM/GCF_Task.h> +#include <GCF/TM/GCF_Port.h> +#include <GCF/GCF_Defines.h> + +namespace LOFAR +{ + namespace GCF + { + namespace Common + { +class GCFPValue; + } + namespace LogSys + { + +/** +*/ + +class GCFKeyValueLogger : public TM::GCFTask +{ + public: + static GCFKeyValueLogger* instance(); + + public: // member functions + void logKeyValue(const string key, const Common::GCFPValue& value, Common::TKVLOrigin origin, const timeval& timestamp); + void logKeyValue(const string key, const Common::GCFPValue& value, Common::TKVLOrigin origin); + + private: + GCFKeyValueLogger (); + virtual ~GCFKeyValueLogger () {} + + private: // state methods + TM::GCFEvent::TResult initial (TM::GCFEvent& e, TM::GCFPortInterface& p); + TM::GCFEvent::TResult operational (TM::GCFEvent& e, TM::GCFPortInterface& p); + + private: // helper methods + + private: // data members + TM::GCFPort _kvlClientPort; + static GCFKeyValueLogger* _pInstance; + + private: // admin members + typedef list<TM::GCFEvent*> TLogQueue; + TLogQueue _logQueue; +}; + } // namespace LogSys + } // namespace GCF +} // namespace LOFAR + +#define LOG_KEYVALUE(key, value, origin, timestamp) \ + LOFAR::GCF::LogSys::GCFKeyValueLogger::instance()->logKeyValue(key, value, origin, timestamp); + +#define LOG_KEYVALUE_DT(key, value, origin) \ + LOFAR::GCF::LogSys::GCFKeyValueLogger::instance()->logKeyValue(key, value, origin); + +#endif