23 #include "mongodb_log_bb_thread.h" 25 #include <core/threading/mutex_locker.h> 26 #include <plugins/mongodb/aspect/mongodb_conncreator.h> 31 #include <mongo/client/dbclient.h> 35 using namespace mongo;
68 std::vector<std::string> includes;
78 if (includes.empty()) {
79 includes.push_back(
"*");
82 std::vector<std::string>::iterator i;
83 std::vector<std::string>::iterator e;
84 for (i = includes.begin(); i != includes.end(); ++i) {
87 std::list<Interface *> current_interfaces =
88 blackboard->open_multiple_for_reading(
"*", i->c_str());
90 std::list<Interface *>::iterator i;
91 for (i = current_interfaces.begin(); i != current_interfaces.end(); ++i) {
93 for (e = excludes_.begin(); e != excludes_.end(); ++e) {
94 if (fnmatch(e->c_str(), (*i)->id(), 0) != FNM_NOMATCH) {
106 listeners_[(*i)->uid()] =
107 new InterfaceListener(
blackboard, *i, mc, database_, collections_,
logger, now_);
119 std::map<std::string, InterfaceListener *>::iterator i;
120 for (i = listeners_.begin(); i != listeners_.end(); ++i) {
121 mongo::DBClientBase *mc = i->second->mongodb_client();
139 std::vector<std::string>::iterator e;
140 for (e = excludes_.begin(); e != excludes_.end(); ++e) {
141 if (fnmatch(e->c_str(), id, 0) != FNM_NOMATCH) {
142 logger->
log_debug(name(),
"Ignoring excluded interface '%s::%s'", type,
id);
148 Interface *
interface = blackboard->open_for_reading(type, id);
149 if (listeners_.find(interface->uid()) == listeners_.end()) {
150 logger->
log_debug(name(),
"Opening new %s", interface->uid());
151 mongo::DBClientBase *mc = mongodb_connmgr->create_client();
152 listeners_[interface->uid()] =
153 new InterfaceListener(blackboard, interface, mc, database_, collections_, logger, now_);
155 logger->
log_warn(name(),
"Interface %s already opened", interface->uid());
156 blackboard->
close(interface);
159 logger->
log_warn(name(),
"Failed to open interface %s::%s, exception follows", type,
id);
173 MongoLogBlackboardThread::InterfaceListener::InterfaceListener(
BlackBoard * blackboard,
175 mongo::DBClientBase * mongodb,
176 std::string & database,
185 interface_ = interface;
191 std::string
id = interface->
id();
193 while ((pos =
id.find_first_of(
" -", pos)) != std::string::npos) {
194 id.replace(pos, 1,
"_");
197 collection_ = database_ +
"." + interface->
type() +
"." + id;
198 if (collections_.find(collection_) != collections_.end()) {
199 throw Exception(
"Collection named %s already used, cannot log %s",
204 bbil_add_data_interface(interface);
205 blackboard_->register_listener(
this, BlackBoard::BBIL_FLAG_DATA);
209 MongoLogBlackboardThread::InterfaceListener::~InterfaceListener()
211 blackboard_->unregister_listener(
this);
215 MongoLogBlackboardThread::InterfaceListener::bb_interface_data_changed(
Interface *interface)
throw()
222 BSONObjBuilder document;
223 document.append(
"timestamp", (
long long)now_->in_msec());
227 bool is_array = (length > 1);
233 BSONArrayBuilder subb(document.subarrayStart(i.
get_name()));
234 for (
size_t l = 0; l < length; ++l) {
235 subb.append(bools[l]);
246 BSONArrayBuilder subb(document.subarrayStart(i.
get_name()));
247 for (
size_t l = 0; l < length; ++l) {
248 subb.append(ints[l]);
259 BSONArrayBuilder subb(document.subarrayStart(i.
get_name()));
260 for (
size_t l = 0; l < length; ++l) {
261 subb.append(ints[l]);
272 BSONArrayBuilder subb(document.subarrayStart(i.
get_name()));
273 for (
size_t l = 0; l < length; ++l) {
274 subb.append(ints[l]);
285 BSONArrayBuilder subb(document.subarrayStart(i.
get_name()));
286 for (
size_t l = 0; l < length; ++l) {
287 subb.append(ints[l]);
298 BSONArrayBuilder subb(document.subarrayStart(i.
get_name()));
299 for (
size_t l = 0; l < length; ++l) {
300 subb.append(ints[l]);
311 BSONArrayBuilder subb(document.subarrayStart(i.
get_name()));
312 for (
size_t l = 0; l < length; ++l) {
313 subb.append(ints[l]);
324 BSONArrayBuilder subb(document.subarrayStart(i.
get_name()));
325 for (
size_t l = 0; l < length; ++l) {
326 subb.append((
long long int)ints[l]);
337 BSONArrayBuilder subb(document.subarrayStart(i.
get_name()));
338 for (
size_t l = 0; l < length; ++l) {
339 subb.append((
long long int)ints[l]);
350 BSONArrayBuilder subb(document.subarrayStart(i.
get_name()));
351 for (
size_t l = 0; l < length; ++l) {
352 subb.append(floats[l]);
363 BSONArrayBuilder subb(document.subarrayStart(i.
get_name()));
364 for (
size_t l = 0; l < length; ++l) {
365 subb.append(doubles[l]);
386 BSONArrayBuilder subb(document.subarrayStart(i.
get_name()));
387 for (
size_t l = 0; l < length; ++l) {
388 subb.append(ints[l]);
398 mongodb_->insert(collection_, document.obj());
399 }
catch (mongo::DBException &e) {
400 logger_->log_warn(bbil_name(),
"Failed to log to %s: %s", collection_.c_str(), e.what());
401 }
catch (std::exception &e) {
402 logger_->log_warn(bbil_name(),
"Failed to log to %s: %s (*)", collection_.c_str(), e.what());
Interface field iterator.
virtual void register_observer(BlackBoardInterfaceObserver *observer)
Register BB interface observer.
uint8_t * get_bytes() const
Get value of current field as byte array.
uint16_t get_uint16(unsigned int index=0) const
Get value of current field as unsigned integer.
int32_t * get_enums() const
Get value of current enum field as integer array.
int32_t get_enum(unsigned int index=0) const
Get value of current enum field as integer.
virtual void log_info(const char *component, const char *format,...)=0
Log informational message.
double get_double(unsigned int index=0) const
Get value of current field as double.
uint16_t * get_uint16s() const
Get value of current field as unsigned integer array.
Fawkes library namespace.
bool get_bool(unsigned int index=0) const
Get value of current field as bool.
8 bit unsigned integer field
float * get_floats() const
Get value of current field as float array.
16 bit unsigned integer field
const char * id() const
Get identifier of interface.
virtual void loop()
Code to execute in the thread.
interface_fieldtype_t get_type() const
Get type of current field.
A class for handling time.
virtual ~MongoLogBlackboardThread()
Destructor.
byte field, alias for uint8
MongoDBConnCreator * mongodb_connmgr
Connection manager to retrieve more client connections from if necessary.
Thread class encapsulation of pthreads.
float get_float(unsigned int index=0) const
Get value of current field as float.
Base class for all Fawkes BlackBoard interfaces.
Logger * logger
This is the Logger member used to access the logger.
uint8_t get_byte(unsigned int index=0) const
Get value of current field as byte.
Clock * clock
By means of this member access to the clock is given.
int16_t get_int16(unsigned int index=0) const
Get value of current field as integer.
int64_t * get_int64s() const
Get value of current field as integer array.
void bbio_add_observed_create(const char *type_pattern, const char *id_pattern="*")
Add interface creation type to watch list.
uint8_t * get_uint8s() const
Get value of current field as unsigned integer array.
const char * type() const
Get type of interface.
int8_t get_int8(unsigned int index=0) const
Get value of current field as integer.
Base class for exceptions in Fawkes.
void read()
Read from BlackBoard into local copy.
int8_t * get_int8s() const
Get value of current field as integer array.
Thread aspect to access MongoDB.
const char * get_name() const
Get name of current field.
uint8_t get_uint8(unsigned int index=0) const
Get value of current field as unsigned integer.
virtual void log_warn(const char *component, const char *format,...)
Log warning message.
double * get_doubles() const
Get value of current field as double array.
virtual void unregister_observer(BlackBoardInterfaceObserver *observer)
Unregister BB interface observer.
virtual mongo::DBClientBase * create_client(const std::string &config_name="")=0
Create a new MongoDB client.
const char * name() const
Get name of thread.
const char * uid() const
Get unique identifier of interface.
uint64_t get_uint64(unsigned int index=0) const
Get value of current field as unsigned integer.
64 bit unsigned integer field
const char * get_string() const
Get value of current field as string.
uint64_t * get_uint64s() const
Get value of current field as unsigned integer array.
uint32_t get_uint32(unsigned int index=0) const
Get value of current field as unsigned integer.
bool * get_bools() const
Get value of current field as bool array.
size_t get_length() const
Get length of current field.
InterfaceFieldIterator fields_end()
Invalid iterator.
uint32_t * get_uint32s() const
Get value of current field as unsigned integer array.
virtual void log_debug(const char *component, const char *format,...)=0
Log debug message.
virtual std::vector< std::string > get_strings(const char *path)=0
Get list of values from configuration which is of type string.
virtual void finalize()
Finalize the thread.
virtual void init()
Initialize the thread.
int32_t * get_int32s() const
Get value of current field as integer array.
The BlackBoard abstract class.
InterfaceFieldIterator fields()
Get iterator over all fields of this interface instance.
virtual void bb_interface_created(const char *type, const char *id)
BlackBoard interface created notification.
MongoLogBlackboardThread()
Constructor.
int32_t get_int32(unsigned int index=0) const
Get value of current field as integer.
int16_t * get_int16s() const
Get value of current field as integer array.
Configuration * config
This is the Configuration member used to access the configuration.
virtual void log_debug(const char *component, const char *format,...)
Log debug message.
32 bit unsigned integer field
field with interface specific enum type
virtual std::string get_string(const char *path)=0
Get value from configuration which is of type string.
BlackBoard interface listener.
virtual void delete_client(mongo::DBClientBase *client)=0
Delete a client.
BlackBoard * blackboard
This is the BlackBoard instance you can use to interact with the BlackBoard.
virtual void close(Interface *interface)=0
Close interface.
int64_t get_int64(unsigned int index=0) const
Get value of current field as integer.