Fawkes API  Fawkes Development Version
mongodb_log_bb_thread.cpp
1 
2 /***************************************************************************
3  * mongodb_log_bb_thread.cpp - MongoDB blackboard logging Thread
4  *
5  * Created: Wed Dec 08 23:09:29 2010
6  * Copyright 2010-2017 Tim Niemueller [www.niemueller.de]
7  * 2012 Bastian Klingen
8  ****************************************************************************/
9 
10 /* This program is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License as published by
12  * the Free Software Foundation; either version 2 of the License, or
13  * (at your option) any later version.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18  * GNU Library General Public License for more details.
19  *
20  * Read the full text in the LICENSE.GPL file in the doc directory.
21  */
22 
23 #include "mongodb_log_bb_thread.h"
24 
25 #include <core/threading/mutex_locker.h>
26 #include <plugins/mongodb/aspect/mongodb_conncreator.h>
27 
28 #include <cstdlib>
29 #include <fnmatch.h>
30 #include <mongocxx/client.hpp>
31 #include <mongocxx/exception/operation_exception.hpp>
32 
33 using namespace mongocxx;
34 using namespace fawkes;
35 
36 /** @class MongoLogBlackboardThread "mongodb_thread.h"
37  * MongoDB Logging Thread.
38  * This thread registers to interfaces specified with patterns in the
39  * configurationa and logs any changes to MongoDB.
40  *
41  * @author Tim Niemueller
42  */
43 
44 /** Constructor. */
46 : Thread("MongoLogBlackboardThread", Thread::OPMODE_WAITFORWAKEUP), MongoDBAspect("default")
47 {
48 }
49 
50 /** Destructor. */
52 {
53 }
54 
55 void
57 {
58  now_ = new Time(clock);
59  database_ = "fflog";
60  try {
61  database_ = config->get_string("/plugins/mongodb-log/database");
62  } catch (Exception &e) {
63  logger->log_info(name(), "No database configured, writing to %s", database_.c_str());
64  }
65 
66  std::vector<std::string> includes;
67  try {
68  includes = config->get_strings("/plugins/mongodb-log/blackboard/includes");
69  } catch (Exception &e) {
70  } // ignored, no include rules
71  try {
72  excludes_ = config->get_strings("/plugins/mongodb-log/blackboard/excludes");
73  } catch (Exception &e) {
74  } // ignored, no include rules
75 
76  if (includes.empty()) {
77  includes.push_back("*");
78  }
79 
80  std::vector<std::string>::iterator i;
81  std::vector<std::string>::iterator e;
82  for (i = includes.begin(); i != includes.end(); ++i) {
83  bbio_add_observed_create("*", i->c_str());
84 
85  std::list<Interface *> current_interfaces =
86  blackboard->open_multiple_for_reading("*", i->c_str());
87 
88  std::list<Interface *>::iterator i;
89  for (i = current_interfaces.begin(); i != current_interfaces.end(); ++i) {
90  bool exclude = false;
91  for (e = excludes_.begin(); e != excludes_.end(); ++e) {
92  if (fnmatch(e->c_str(), (*i)->id(), 0) != FNM_NOMATCH) {
93  logger->log_debug(name(), "Excluding '%s' by config rule", (*i)->uid());
94  blackboard->close(*i);
95  exclude = true;
96  break;
97  }
98  }
99  if (exclude)
100  continue;
101 
102  logger->log_debug(name(), "Adding %s", (*i)->uid());
103  client * mc = mongodb_connmgr->create_client();
104  std::string agent_name = config->get_string_or_default("/fawkes/agent/name", "");
105  listeners_[(*i)->uid()] = new InterfaceListener(
106  blackboard, *i, mc, database_, collections_, agent_name, logger, now_);
107  }
108  }
109 
111 }
112 
113 void
115 {
117 
118  std::map<std::string, InterfaceListener *>::iterator i;
119  for (i = listeners_.begin(); i != listeners_.end(); ++i) {
120  client *mc = i->second->mongodb_client();
121  delete i->second;
123  }
124  listeners_.clear();
125 }
126 
127 void
129 {
130 }
131 
132 // for BlackBoardInterfaceObserver
133 void
134 MongoLogBlackboardThread::bb_interface_created(const char *type, const char *id) throw()
135 {
136  MutexLocker lock(listeners_.mutex());
137 
138  std::vector<std::string>::iterator e;
139  for (e = excludes_.begin(); e != excludes_.end(); ++e) {
140  if (fnmatch(e->c_str(), id, 0) != FNM_NOMATCH) {
141  logger->log_debug(name(), "Ignoring excluded interface '%s::%s'", type, id);
142  return;
143  }
144  }
145 
146  try {
147  Interface *interface = blackboard->open_for_reading(type, id);
148  if (listeners_.find(interface->uid()) == listeners_.end()) {
149  logger->log_debug(name(), "Opening new %s", interface->uid());
150  client * mc = mongodb_connmgr->create_client();
151  std::string agent_name = config->get_string_or_default("/fawkes/agent/name", "");
152  listeners_[interface->uid()] = new InterfaceListener(
153  blackboard, interface, mc, database_, collections_, agent_name, logger, now_);
154  } else {
155  logger->log_warn(name(), "Interface %s already opened", interface->uid());
156  blackboard->close(interface);
157  }
158  } catch (Exception &e) {
159  logger->log_warn(name(), "Failed to open interface %s::%s, exception follows", type, id);
160  logger->log_warn(name(), e);
161  }
162 }
163 
164 /** Constructor.
165  * @param blackboard blackboard
166  * @param interface interface to listen for
167  * @param mongodb MongoDB client to write to
168  * @param database name of database to write to
169  * @param colls collections
170  * @param agent_name agent belonging to the fawkes instance.
171  * @param logger logger
172  * @param now Time
173  */
174 MongoLogBlackboardThread::InterfaceListener::InterfaceListener(BlackBoard * blackboard,
175  Interface * interface,
176  client * mongodb,
177  std::string & database,
178  LockSet<std::string> &colls,
179  const std::string & agent_name,
180  Logger * logger,
181  Time * now)
182 : BlackBoardInterfaceListener("MongoLogListener-%s", interface->uid()),
183  database_(database),
184  collections_(colls),
185  agent_name_(agent_name)
186 {
187  blackboard_ = blackboard;
188  interface_ = interface;
189  mongodb_ = mongodb;
190  logger_ = logger;
191  now_ = now;
192 
193  // sanitize interface ID to be suitable for MongoDB
194  std::string id = interface->id();
195  size_t pos = 0;
196  while ((pos = id.find_first_of(" -", pos)) != std::string::npos) {
197  id.replace(pos, 1, "_");
198  pos = pos + 1;
199  }
200  collection_ = std::string(interface->type()) + "." + id;
201  if (collections_.find(collection_) != collections_.end()) {
202  throw Exception("Collection named %s already used, cannot log %s",
203  collection_.c_str(),
204  interface->uid());
205  }
206 
207  bbil_add_data_interface(interface);
208  blackboard_->register_listener(this, BlackBoard::BBIL_FLAG_DATA);
209 }
210 
211 /** Destructor. */
212 MongoLogBlackboardThread::InterfaceListener::~InterfaceListener()
213 {
214  blackboard_->unregister_listener(this);
215 }
216 
217 void
218 MongoLogBlackboardThread::InterfaceListener::bb_interface_data_changed(Interface *interface) throw()
219 {
220  now_->stamp();
221  interface->read();
222 
223  try {
224  // write interface data
225  using namespace bsoncxx::builder;
226  basic::document document;
227  document.append(basic::kvp("timestamp", static_cast<int64_t>(now_->in_msec())));
229  for (i = interface->fields(); i != interface->fields_end(); ++i) {
230  size_t length = i.get_length();
231  bool is_array = (length > 1);
232 
233  std::string key{i.get_name()};
234  switch (i.get_type()) {
235  case IFT_BOOL:
236  if (is_array) {
237  bool *bools = i.get_bools();
238  document.append(basic::kvp(key, [bools, length](basic::sub_array subarray) {
239  for (size_t l = 0; l < length; ++l) {
240  subarray.append(bools[l]);
241  }
242  }));
243  } else {
244  document.append(basic::kvp(key, i.get_bool()));
245  }
246  break;
247 
248  case IFT_INT8:
249  if (is_array) {
250  int8_t *ints = i.get_int8s();
251  document.append(basic::kvp(key, [ints, length](basic::sub_array subarray) {
252  for (size_t l = 0; l < length; ++l) {
253  subarray.append(ints[l]);
254  }
255  }));
256  } else {
257  document.append(basic::kvp(key, i.get_int8()));
258  }
259  break;
260 
261  case IFT_UINT8:
262  if (is_array) {
263  uint8_t *ints = i.get_uint8s();
264  document.append(basic::kvp(key, [ints, length](basic::sub_array subarray) {
265  for (size_t l = 0; l < length; ++l) {
266  subarray.append(ints[l]);
267  }
268  }));
269  } else {
270  document.append(basic::kvp(key, i.get_uint8()));
271  }
272  break;
273 
274  case IFT_INT16:
275  if (is_array) {
276  int16_t *ints = i.get_int16s();
277  document.append(basic::kvp(key, [ints, length](basic::sub_array subarray) {
278  for (size_t l = 0; l < length; ++l) {
279  subarray.append(ints[l]);
280  }
281  }));
282  } else {
283  document.append(basic::kvp(key, i.get_int16()));
284  }
285  break;
286 
287  case IFT_UINT16:
288  if (is_array) {
289  uint16_t *ints = i.get_uint16s();
290  document.append(basic::kvp(key, [ints, length](basic::sub_array subarray) {
291  for (size_t l = 0; l < length; ++l) {
292  subarray.append(ints[l]);
293  }
294  }));
295  } else {
296  document.append(basic::kvp(key, i.get_uint16()));
297  }
298  break;
299 
300  case IFT_INT32:
301  if (is_array) {
302  int32_t *ints = i.get_int32s();
303  document.append(basic::kvp(key, [ints, length](basic::sub_array subarray) {
304  for (size_t l = 0; l < length; ++l) {
305  subarray.append(ints[l]);
306  }
307  }));
308  } else {
309  document.append(basic::kvp(key, i.get_int32()));
310  }
311  break;
312 
313  case IFT_UINT32:
314  if (is_array) {
315  uint32_t *ints = i.get_uint32s();
316  document.append(basic::kvp(key, [ints, length](basic::sub_array subarray) {
317  for (size_t l = 0; l < length; ++l) {
318  subarray.append(static_cast<int64_t>(ints[l]));
319  }
320  }));
321  } else {
322  document.append(basic::kvp(key, static_cast<int64_t>(i.get_uint32())));
323  }
324  break;
325 
326  case IFT_INT64:
327  if (is_array) {
328  int64_t *ints = i.get_int64s();
329  document.append(basic::kvp(key, [ints, length](basic::sub_array subarray) {
330  for (size_t l = 0; l < length; ++l) {
331  subarray.append(ints[l]);
332  }
333  }));
334  } else {
335  document.append(basic::kvp(key, i.get_int64()));
336  }
337  break;
338 
339  case IFT_UINT64:
340  if (is_array) {
341  uint64_t *ints = i.get_uint64s();
342  document.append(basic::kvp(key, [ints, length](basic::sub_array subarray) {
343  for (size_t l = 0; l < length; ++l) {
344  subarray.append(static_cast<int64_t>(ints[l]));
345  }
346  }));
347  } else {
348  document.append(basic::kvp(key, static_cast<int64_t>(i.get_uint64())));
349  }
350  break;
351 
352  case IFT_FLOAT:
353  if (is_array) {
354  float *floats = i.get_floats();
355  document.append(basic::kvp(key, [floats, length](basic::sub_array subarray) {
356  for (size_t l = 0; l < length; ++l) {
357  subarray.append(floats[l]);
358  }
359  }));
360  } else {
361  document.append(basic::kvp(key, i.get_float()));
362  }
363  break;
364 
365  case IFT_DOUBLE:
366  if (is_array) {
367  double *doubles = i.get_doubles();
368  document.append(basic::kvp(key, [doubles, length](basic::sub_array subarray) {
369  for (size_t l = 0; l < length; ++l) {
370  subarray.append(doubles[l]);
371  }
372  }));
373  } else {
374  document.append(basic::kvp(key, i.get_double()));
375  }
376  break;
377 
378  case IFT_STRING: document.append(basic::kvp(key, i.get_string())); break;
379 
380  case IFT_BYTE:
381  if (is_array) {
382  uint8_t *bytes = i.get_bytes();
383  document.append(basic::kvp(key, [bytes, length](basic::sub_array subarray) {
384  for (size_t l = 0; l < length; ++l) {
385  subarray.append(bytes[l]);
386  }
387  }));
388  } else {
389  document.append(basic::kvp(key, i.get_byte()));
390  }
391  break;
392 
393  case IFT_ENUM:
394  if (is_array) {
395  int32_t *ints = i.get_enums();
396  document.append(basic::kvp(key, [ints, length](basic::sub_array subarray) {
397  for (size_t l = 0; l < length; ++l) {
398  subarray.append(ints[l]);
399  }
400  }));
401  } else {
402  document.append(basic::kvp(key, i.get_enum()));
403  }
404  break;
405  }
406  }
407 
408  document.append(basic::kvp("agent-name", agent_name_));
409  mongodb_->database(database_)[collection_].insert_one(document.view());
410  } catch (operation_exception &e) {
411  logger_->log_warn(
412  bbil_name(), "Failed to log to %s.%s: %s", database_.c_str(), collection_.c_str(), e.what());
413  } catch (std::exception &e) {
414  logger_->log_warn(bbil_name(),
415  "Failed to log to %s.%s: %s (*)",
416  database_.c_str(),
417  collection_.c_str(),
418  e.what());
419  }
420 }
fawkes::InterfaceFieldIterator::get_enums
int32_t * get_enums() const
Get value of current enum field as integer array.
Definition: field_iterator.cpp:927
fawkes::MongoDBAspect
Thread aspect to access MongoDB.
Definition: mongodb.h:39
MongoLogBlackboardThread::MongoLogBlackboardThread
MongoLogBlackboardThread()
Constructor.
Definition: mongodb_log_bb_thread.cpp:45
fawkes::IFT_UINT8
@ IFT_UINT8
8 bit unsigned integer field
Definition: types.h:39
fawkes::InterfaceFieldIterator::get_bytes
uint8_t * get_bytes() const
Get value of current field as byte array.
Definition: field_iterator.cpp:909
fawkes::Interface::fields_end
InterfaceFieldIterator fields_end()
Invalid iterator.
Definition: interface.cpp:1207
fawkes::MongoDBConnCreator::create_client
virtual mongocxx::client * create_client(const std::string &config_name="")=0
Create a new MongoDB client.
fawkes::InterfaceFieldIterator::get_floats
float * get_floats() const
Get value of current field as float array.
Definition: field_iterator.cpp:873
fawkes::IFT_UINT64
@ IFT_UINT64
64 bit unsigned integer field
Definition: types.h:45
fawkes::Interface::read
void read()
Read from BlackBoard into local copy.
Definition: interface.cpp:472
fawkes::IFT_INT8
@ IFT_INT8
8 bit integer field
Definition: types.h:38
fawkes::IFT_BOOL
@ IFT_BOOL
boolean field
Definition: types.h:37
fawkes::LockSet< std::string >
fawkes::MongoDBAspect::mongodb_connmgr
MongoDBConnCreator * mongodb_connmgr
Connection manager to retrieve more client connections from if necessary.
Definition: mongodb.h:55
fawkes::InterfaceFieldIterator::get_uint16s
uint16_t * get_uint16s() const
Get value of current field as unsigned integer array.
Definition: field_iterator.cpp:783
fawkes::IFT_FLOAT
@ IFT_FLOAT
float field
Definition: types.h:46
fawkes::IFT_ENUM
@ IFT_ENUM
field with interface specific enum type
Definition: types.h:50
fawkes::IFT_UINT16
@ IFT_UINT16
16 bit unsigned integer field
Definition: types.h:41
fawkes::Logger::log_info
virtual void log_info(const char *component, const char *format,...)=0
Log informational message.
fawkes::IFT_UINT32
@ IFT_UINT32
32 bit unsigned integer field
Definition: types.h:43
fawkes::MutexLocker
Mutex locking helper.
Definition: mutex_locker.h:34
fawkes::BlackBoardInterfaceListener
BlackBoard interface listener.
Definition: interface_listener.h:42
MongoLogBlackboardThread::init
virtual void init()
Initialize the thread.
Definition: mongodb_log_bb_thread.cpp:56
MongoLogBlackboardThread::finalize
virtual void finalize()
Finalize the thread.
Definition: mongodb_log_bb_thread.cpp:114
fawkes::BlackBoard
The BlackBoard abstract class.
Definition: blackboard.h:46
fawkes::InterfaceFieldIterator::get_byte
uint8_t get_byte(unsigned int index=0) const
Get value of current field as byte.
Definition: field_iterator.cpp:640
fawkes::Interface::type
const char * type() const
Get type of interface.
Definition: interface.cpp:643
fawkes::InterfaceFieldIterator::get_int64s
int64_t * get_int64s() const
Get value of current field as integer array.
Definition: field_iterator.cpp:837
fawkes::Thread::name
const char * name() const
Get name of thread.
Definition: thread.h:100
MongoLogBlackboardThread::loop
virtual void loop()
Code to execute in the thread.
Definition: mongodb_log_bb_thread.cpp:128
fawkes::Interface::id
const char * id() const
Get identifier of interface.
Definition: interface.cpp:652
fawkes::ClockAspect::clock
Clock * clock
By means of this member access to the clock is given.
Definition: clock.h:42
fawkes::BlackBoardInterfaceObserver::bbio_add_observed_create
void bbio_add_observed_create(const char *type_pattern, const char *id_pattern="*")
Add interface creation type to watch list.
Definition: interface_observer.cpp:119
fawkes::InterfaceFieldIterator::get_bool
bool get_bool(unsigned int index=0) const
Get value of current field as bool.
Definition: field_iterator.cpp:409
fawkes::MultiLogger::log_debug
virtual void log_debug(const char *component, const char *format,...)
Log debug message.
Definition: multi.cpp:174
fawkes::MultiLogger::log_warn
virtual void log_warn(const char *component, const char *format,...)
Log warning message.
Definition: multi.cpp:216
fawkes::InterfaceFieldIterator
Interface field iterator.
Definition: field_iterator.h:39
fawkes::InterfaceFieldIterator::get_uint8s
uint8_t * get_uint8s() const
Get value of current field as unsigned integer array.
Definition: field_iterator.cpp:747
fawkes::InterfaceFieldIterator::get_type
interface_fieldtype_t get_type() const
Get type of current field.
Definition: field_iterator.cpp:192
MongoLogBlackboardThread::~MongoLogBlackboardThread
virtual ~MongoLogBlackboardThread()
Destructor.
Definition: mongodb_log_bb_thread.cpp:51
fawkes::IFT_INT32
@ IFT_INT32
32 bit integer field
Definition: types.h:42
fawkes::LoggingAspect::logger
Logger * logger
This is the Logger member used to access the logger.
Definition: logging.h:41
fawkes::BlackBoard::close
virtual void close(Interface *interface)=0
Close interface.
fawkes::Logger
Interface for logging.
Definition: logger.h:42
fawkes::InterfaceFieldIterator::get_float
float get_float(unsigned int index=0) const
Get value of current field as float.
Definition: field_iterator.cpp:598
fawkes::InterfaceFieldIterator::get_uint8
uint8_t get_uint8(unsigned int index=0) const
Get value of current field as unsigned integer.
Definition: field_iterator.cpp:451
fawkes
Fawkes library namespace.
fawkes::InterfaceFieldIterator::get_uint32
uint32_t get_uint32(unsigned int index=0) const
Get value of current field as unsigned integer.
Definition: field_iterator.cpp:535
fawkes::InterfaceFieldIterator::get_uint64
uint64_t get_uint64(unsigned int index=0) const
Get value of current field as unsigned integer.
Definition: field_iterator.cpp:577
fawkes::InterfaceFieldIterator::get_doubles
double * get_doubles() const
Get value of current field as double array.
Definition: field_iterator.cpp:891
fawkes::InterfaceFieldIterator::get_int32s
int32_t * get_int32s() const
Get value of current field as integer array.
Definition: field_iterator.cpp:801
fawkes::InterfaceFieldIterator::get_int8
int8_t get_int8(unsigned int index=0) const
Get value of current field as integer.
Definition: field_iterator.cpp:430
fawkes::Configuration::get_strings
virtual std::vector< std::string > get_strings(const char *path)=0
Get list of values from configuration which is of type string.
fawkes::InterfaceFieldIterator::get_name
const char * get_name() const
Get name of current field.
Definition: field_iterator.cpp:261
fawkes::BlackBoard::register_observer
virtual void register_observer(BlackBoardInterfaceObserver *observer)
Register BB interface observer.
Definition: blackboard.cpp:225
fawkes::Interface
Base class for all Fawkes BlackBoard interfaces.
Definition: interface.h:79
fawkes::InterfaceFieldIterator::get_int16
int16_t get_int16(unsigned int index=0) const
Get value of current field as integer.
Definition: field_iterator.cpp:472
fawkes::InterfaceFieldIterator::get_int8s
int8_t * get_int8s() const
Get value of current field as integer array.
Definition: field_iterator.cpp:729
fawkes::ConfigurableAspect::config
Configuration * config
This is the Configuration member used to access the configuration.
Definition: configurable.h:41
fawkes::InterfaceFieldIterator::get_bools
bool * get_bools() const
Get value of current field as bool array.
Definition: field_iterator.cpp:709
fawkes::InterfaceFieldIterator::get_string
const char * get_string() const
Get value of current field as string.
Definition: field_iterator.cpp:944
fawkes::Interface::uid
const char * uid() const
Get unique identifier of interface.
Definition: interface.cpp:677
fawkes::InterfaceFieldIterator::get_int16s
int16_t * get_int16s() const
Get value of current field as integer array.
Definition: field_iterator.cpp:765
fawkes::InterfaceFieldIterator::get_uint64s
uint64_t * get_uint64s() const
Get value of current field as unsigned integer array.
Definition: field_iterator.cpp:855
fawkes::IFT_INT64
@ IFT_INT64
64 bit integer field
Definition: types.h:44
fawkes::InterfaceFieldIterator::get_length
size_t get_length() const
Get length of current field.
Definition: field_iterator.cpp:287
fawkes::Interface::fields
InterfaceFieldIterator fields()
Get iterator over all fields of this interface instance.
Definition: interface.cpp:1198
fawkes::Time
A class for handling time.
Definition: time.h:93
MongoLogBlackboardThread::bb_interface_created
virtual void bb_interface_created(const char *type, const char *id)
BlackBoard interface created notification.
Definition: mongodb_log_bb_thread.cpp:134
fawkes::IFT_DOUBLE
@ IFT_DOUBLE
double field
Definition: types.h:47
fawkes::InterfaceFieldIterator::get_uint32s
uint32_t * get_uint32s() const
Get value of current field as unsigned integer array.
Definition: field_iterator.cpp:819
fawkes::Thread
Thread class encapsulation of pthreads.
Definition: thread.h:46
fawkes::BlackBoard::unregister_observer
virtual void unregister_observer(BlackBoardInterfaceObserver *observer)
Unregister BB interface observer.
Definition: blackboard.cpp:240
fawkes::BlackBoardAspect::blackboard
BlackBoard * blackboard
This is the BlackBoard instance you can use to interact with the BlackBoard.
Definition: blackboard.h:44
fawkes::Configuration::get_string
virtual std::string get_string(const char *path)=0
Get value from configuration which is of type string.
fawkes::Configuration::get_string_or_default
virtual std::string get_string_or_default(const char *path, const std::string &default_val)
Get value from configuration which is of type string, or the given default if the path does not exist...
Definition: config.cpp:736
fawkes::IFT_STRING
@ IFT_STRING
string field
Definition: types.h:48
fawkes::BlackBoard::open_multiple_for_reading
virtual std::list< Interface * > open_multiple_for_reading(const char *type_pattern, const char *id_pattern="*", const char *owner=NULL)=0
Open multiple interfaces for reading.
fawkes::MongoDBConnCreator::delete_client
virtual void delete_client(mongocxx::client *client)=0
Delete a client.
fawkes::IFT_BYTE
@ IFT_BYTE
byte field, alias for uint8
Definition: types.h:49
fawkes::IFT_INT16
@ IFT_INT16
16 bit integer field
Definition: types.h:40
fawkes::InterfaceFieldIterator::get_int32
int32_t get_int32(unsigned int index=0) const
Get value of current field as integer.
Definition: field_iterator.cpp:514
fawkes::InterfaceFieldIterator::get_enum
int32_t get_enum(unsigned int index=0) const
Get value of current enum field as integer.
Definition: field_iterator.cpp:661
fawkes::InterfaceFieldIterator::get_double
double get_double(unsigned int index=0) const
Get value of current field as double.
Definition: field_iterator.cpp:619
fawkes::Logger::log_debug
virtual void log_debug(const char *component, const char *format,...)=0
Log debug message.
fawkes::InterfaceFieldIterator::get_int64
int64_t get_int64(unsigned int index=0) const
Get value of current field as integer.
Definition: field_iterator.cpp:556
fawkes::InterfaceFieldIterator::get_uint16
uint16_t get_uint16(unsigned int index=0) const
Get value of current field as unsigned integer.
Definition: field_iterator.cpp:493
fawkes::Exception
Base class for exceptions in Fawkes.
Definition: exception.h:36