Commit b9779761 authored by Olivier Dion's avatar Olivier Dion

agent: Add log recording behavior

Change-Id: I702ab3422c3fd6bd528fe65a5541c98150a5722d
parent 879185f8
......@@ -5,6 +5,6 @@ AM_CXXFLAGS += -I$(top_srcdir)/src -I.. \
check_PROGRAMS = agent
agent_SOURCES = agent.cpp agent.h utils.cpp utils.h bt.cpp bt.h main.cpp
agent_SOURCES = agent.cpp agent.h utils.cpp utils.h bt.cpp bt.h main.cpp log.h
agent_LDADD = $(top_builddir)/src/libring.la -ldl
......@@ -66,6 +66,8 @@ Agent::initBehavior()
BT::register_behavior("make-call", bind(&Agent::makeCall, this));
BT::register_behavior("true", bind(&Agent::True, this));
BT::register_behavior("false", bind(&Agent::False, this));
BT::register_behavior("start-log-recording", bind(&Agent::startLogRecording, this));
BT::register_behavior("stop-log-recording", bind(&Agent::stopLogRecording, this));
}
void
......@@ -77,6 +79,18 @@ Agent::configure(const std::string& yaml_config)
YAML::Node node = YAML::Load(file);
auto context = node["record-context"];
if (context.IsScalar()) {
context_ = context.as<std::string>();
}
auto to = node["record-to"];
if (to.IsScalar()) {
recordTo_ = to.as<std::string>();
}
auto peers = node["peers"];
AGENT_ASSERT(peers.IsSequence(), "Configuration node `peers` must be a sequence");
......@@ -202,6 +216,9 @@ Agent::installSignalHandlers()
_2,
_3)));
handlers.insert(DRing::exportable_callback<DRing::ConfigurationSignal::MessageSend>(
bind(&Agent::onLogging, this, _1)));
DRing::registerSignalHandlers(handlers);
}
......@@ -278,6 +295,14 @@ Agent::registerStaticCallbacks()
});
}
void
Agent::onLogging(const std::string& message)
{
for (const auto& [context, logger] : loggers_) {
logger->pushMessage(message);
}
}
bool
Agent::searchPeer()
{
......@@ -363,6 +388,50 @@ Agent::sendMessage(const std::string& to, const std::string& msg)
/* Behavior start here */
bool
Agent::startLogRecording()
{
class FileHandler : public LogHandler
{
std::ofstream out;
public:
FileHandler(const std::string& context, const std::string& to)
: LogHandler(context)
, out(to)
{}
virtual void pushMessage(const std::string& message) override
{
out << context_ << message << std::endl;
}
virtual void flush() override { out.flush(); }
};
loggers_[context_] = std::make_unique<FileHandler>(context_, recordTo_);
setMonitorLog(true);
return true;
}
bool
Agent::stopLogRecording()
{
LOG_AGENT_STATE();
if (not loggers_.empty()) {
loggers_.erase(context_);
}
if (loggers_.empty()) {
setMonitorLog(false);
}
return true;
}
bool
Agent::echo()
{
......
......@@ -22,6 +22,7 @@
/* agent */
#include "agent/bt.h"
#include "agent/log.h"
/* Dring */
#include "dring/dring.h"
......@@ -80,6 +81,7 @@ class Agent
onIncomingCall_;
Handler<const std::string&, const std::string&, bool> onContactAdded_;
/* Initialize agent */
void configure(const std::string& yaml_config);
void getConversations();
......@@ -89,17 +91,25 @@ class Agent
void registerStaticCallbacks();
/* Bookkeeping */
std::string context_;
std::string recordTo_;
std::string peerID_;
const std::string accountID_{"afafafafafafafaf"};
std::vector<std::string> peers_;
std::vector<std::string> conversations_;
std::unique_ptr<BT::Node> root_;
std::vector<std::function<void(void)>> params_;
std::map<std::string, std::unique_ptr<LogHandler>> loggers_;
/* Event */
void onLogging(const std::string& message);
/* Helper */
void sendMessage(const std::string& to, const std::string& msg);
/* Behavior */
bool startLogRecording();
bool stopLogRecording();
bool searchPeer();
bool wait();
bool echo();
......
behavior:
- search-peer
- start-log-recording
# - : [ echo, true ]
# - : [ make-call, true ]
- stop-log-recording
- wait
record-context: "My context: "
record-to: "out.txt"
peers:
- "your-peer-id"
......
/*
* Copyright (C) 2021 Savoir-faire Linux Inc.
*
* Author: Olivier Dion <olivier.dion@savoirfairelinux.com>
*
* 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 3 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#pragma once
#include <string>
class LogHandler
{
protected:
std::string context_;
public:
LogHandler(const std::string& context)
: context_(context)
{}
virtual ~LogHandler() = default;
virtual void pushMessage(const std::string& message) = 0;
virtual void flush() = 0;
};
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