29void LogEntry::clear_logEntries()
38 entry_list_max_size = size;
45 entry_list_max_size_enabled=enable;
50 if (
logInfo.
logsize >= entry_list_max_size && entry_list_max_size_enabled)
98 if (level > highest_error) {
99 highest_error = level;
106 std::string logger_portname = log_updater->getPortName();
107 p.
open(logger_portname+
"/discover");
113 p.
write(cmd,response);
114 printf (
"%s\n\n", response.
toString().c_str());
115 int size = response.
size();
116 for (
int i=1; i<size; i++)
124 char* log_off =
nullptr;
125 char* yarprun_log_off =
nullptr;
126 log_off = std::strstr((
char*)(n2->
get(1).
toString().c_str()),
"/log/");
130 printf (
"%s\n", logport.c_str());
131 ports.push_back(logport);
133 yarprun_log_off = std::strstr((
char*)(n2->
get(1).
toString().c_str()),
"/yarprunlog/");
137 printf (
"%s\n", logport.c_str());
138 ports.push_back(logport);
144 std::list<std::string>::iterator ports_it;
145 for (ports_it=ports.begin(); ports_it!=ports.end(); ports_it++)
147 LogEntry entry (log_updater->logs_max_lines_enabled, log_updater->logs_max_lines);
158 std::istringstream iss(*ports_it);
160 getline(iss, token,
'/');
161 getline(iss, token,
'/');
166 std::list<LogEntry>::iterator it;
167 this->log_updater->mutex.lock();
169 for (it = this->log_updater->log_list.begin(); it != log_updater->log_list.end(); it++)
178 log_updater->log_list.push_back(entry);
180 this->log_updater->mutex.unlock();
190 std::list<std::string>::const_iterator it;
191 for (it = ports.begin(); it != ports.end(); it++)
204std::string LoggerEngine::logger_thread::getPortName()
206 return logger_portName;
209LoggerEngine::logger_thread::logger_thread (std::string _portname,
double _period,
int _log_list_max_size,
int _logs_max_lines) :
212 logger_portName = _portname;
213 log_list_max_size = _log_list_max_size;
214 log_list_max_size_enabled =
true;
215 logs_max_lines = _logs_max_lines;
216 logs_max_lines_enabled =
true;
217 unknown_format_received = 0;
220void LoggerEngine::logger_thread::run()
226 int bufferport_size = logger_port.getPendingReads();
227 int processed_events = 0;
229 while (bufferport_size>0)
233 if (processed_events > 1000)
235 fprintf(stderr,
"DEBUG: processing log events... Remaining events: %d\n", bufferport_size);
240 std::time_t machine_current_time = std::time(
nullptr);
241 char machine_current_time_c [50];
245 sprintf(machine_current_time_c,
"%f",d_time);
246 std::string machine_current_time_s = std::string(machine_current_time_c);
249 bufferport_size = logger_port.getPendingReads();
253 fprintf (stderr,
"ERROR: something strange happened here, bufferport_size = %d!\n",bufferport_size);
259 fprintf (stderr,
"ERROR: unknown log format!\n");
260 unknown_format_received++;
264 std::string bottlestring = b->
toString();
273 fprintf(stderr,
"ERROR: unknown log format!\n");
274 unknown_format_received++;
282 sprintf(ttstr,
"%d",count++);
294 fprintf(stderr,
"ERROR: unknown log format!\n");
295 unknown_format_received++;
301 if (p.check(
"level")) {
302 body.
text = p.find(
"message").toString();
304 auto level = p.find(
"level").toString();
305 if (level ==
"TRACE") {
307 }
else if (level ==
"DEBUG") {
309 }
else if (level ==
"INFO") {
311 }
else if (level ==
"WARNING") {
313 }
else if (level ==
"ERROR") {
315 }
else if (level ==
"FATAL") {
321 if (p.check(
"filename")) {
322 body.
filename = p.find(
"filename").asString();
327 if (p.check(
"line")) {
328 body.
line =
static_cast<uint32_t
>(p.find(
"line").asInt32());
333 if (p.check(
"function")) {
334 body.
function = p.find(
"function").asString();
339 if (p.check(
"hostname")) {
340 body.
hostname = p.find(
"hostname").asString();
345 if (p.check(
"pid")) {
346 body.
pid = p.find(
"pid").asInt32();
351 if (p.check(
"cmd")) {
352 body.
cmd = p.find(
"cmd").asString();
357 if (p.check(
"args")) {
358 body.
args = p.find(
"args").asString();
363 if (p.check(
"thread_id")) {
364 body.
thread_id = p.find(
"thread_id").asInt64();
369 if (p.check(
"component")) {
370 body.
component = p.find(
"component").asString();
376 body.
id = p.find(
"id").asString();
381 if (p.check(
"systemtime")) {
382 body.
systemtime = p.find(
"systemtime").asFloat64();
387 if (p.check(
"networktime")) {
388 body.
networktime = p.find(
"networktime").asFloat64();
394 if (p.check(
"externaltime")) {
400 if (p.check(
"backtrace")) {
401 body.
backtrace = p.find(
"backtrace").asString();
412 size_t str = s.find(
'[',0);
413 size_t end = s.find(
']',0);
414 if (str==std::string::npos || end==std::string::npos )
420 std::string level = s.substr(str,end+1);
422 if (level.find(
"TRACE") != std::string::npos) {
424 }
else if (level.find(
"DEBUG") != std::string::npos) {
426 }
else if (level.find(
"INFO") != std::string::npos) {
428 }
else if (level.find(
"WARNING") != std::string::npos) {
430 }
else if (level.find(
"ERROR") != std::string::npos) {
432 }
else if (level.find(
"FATAL") != std::string::npos) {
435 body.
text = s.substr(end+1);
451 LogEntry entry (this->logs_max_lines_enabled, this->logs_max_lines);
452 entry.logInfo.port_complete = header;
453 entry.logInfo.port_complete.erase(0,1);
454 entry.logInfo.port_complete.erase(entry.logInfo.port_complete.size()-1);
455 std::istringstream iss(header);
457 getline(iss, token,
'/');
458 getline(iss, token,
'/'); entry.logInfo.port_system = token;
459 getline(iss, token,
'/'); entry.logInfo.port_prefix =
"/"+ token;
460 getline(iss, token,
'/'); entry.logInfo.process_name = token;
461 getline(iss, token,
'/'); entry.logInfo.process_pid = token.erase(token.size()-1);
462 if (entry.logInfo.port_system ==
"log" && listen_to_YARP_MESSAGES ==
false) {
465 if (entry.logInfo.port_system ==
"yarprunlog" && listen_to_YARPRUN_MESSAGES ==
false) {
472 std::list<LogEntry>::iterator it;
473 for (it = log_list.begin(); it != log_list.end(); it++)
475 if (it->logInfo.port_complete==entry.logInfo.port_complete)
477 if (it->logging_enabled)
479 it->logInfo.setNewError(body.
level);
480 it->logInfo.last_update=machine_current_time;
481 it->append_logEntry(body);
490 if (it == log_list.end())
492 if (log_list.size() < log_list_max_size || log_list_max_size_enabled==
false )
497 entry.logInfo.setNewError(body.
level);
498 entry.logInfo.ip_address = contact.
getHost();
502 printf(
"ERROR: invalid contact: %s\n", entry.logInfo.port_complete.c_str());
504 entry.append_logEntry(body);
505 entry.logInfo.last_update=machine_current_time;
506 log_list.push_back(entry);
513 this->mutex.unlock();
525 fprintf(stderr,
"logger is already running, listening on port %s\n", log_updater->getPortName().c_str());
531 fprintf(stderr,
"Unable to start logger: port %s is unavailable because another instance of the logger is already running (or address conflict)\n", log_updater->getPortName().c_str());
535 if (log_updater->logger_port.open(log_updater->getPortName()))
537 fprintf(stdout,
"Logger successfully started, listening on port %s\n", log_updater->getPortName().c_str());
541 fprintf(stderr,
"Unable to start logger: port %s is unavailable\n", log_updater->getPortName().c_str());
544 log_updater->logger_port.resume();
545 log_updater->logger_port.setStrict();
547 log_updater->start();
551void LoggerEngine::logger_thread::threadRelease()
553 logger_port.interrupt();
559 if (log_updater ==
nullptr) {
560 fprintf(stdout,
"Logger stop internal error");
565 if (log_updater->isRunning() ==
true) {
569 fprintf(stdout,
"Logger successfully stopped");
575 if (log_updater ==
nullptr) {
576 fprintf(stdout,
"Logger start_discoverry internal error");
580 fprintf(stdout,
"Logger discovery started");
581 log_updater->start();
587 fprintf(stdout,
"Logger discovery stopped");
593 log_updater=
new logger_thread (portName, 0.01);
601 if (log_updater!=
nullptr)
604 log_updater =
nullptr;
610 if (log_updater ==
nullptr) {
614 return log_updater->logger_port.getInputCount();
619 if (log_updater ==
nullptr) {
623 log_updater->mutex.lock();
624 std::list<LogEntry>::iterator it;
625 for (it = log_updater->log_list.begin(); it != log_updater->log_list.end(); it++)
627 infos.push_back(it->logInfo);
629 log_updater->mutex.unlock();
634 if (log_updater ==
nullptr) {
638 log_updater->mutex.lock();
639 std::list<LogEntry>::iterator it;
640 for (it = log_updater->log_list.begin(); it != log_updater->log_list.end(); it++)
642 messages.insert(messages.end(), it->entry_list.begin(), it->entry_list.end());
644 log_updater->mutex.unlock();
649 if (log_updater ==
nullptr) {
653 log_updater->mutex.lock();
654 std::list<LogEntry>::iterator it;
655 for (it = log_updater->log_list.begin(); it != log_updater->log_list.end(); it++)
657 if (it->logInfo.port_prefix == port)
660 if (it->last_read_message==-1)
664 if (from_beginning==
true)
666 it->last_read_message = 0;
668 int i=it->last_read_message;
669 for (; i<(int)it->entry_list.size(); i++)
671 messages.push_back(it->entry_list[i]);
673 it->last_read_message=i;
677 log_updater->mutex.unlock();
682 if (log_updater ==
nullptr) {
686 log_updater->mutex.lock();
687 std::list<LogEntry>::iterator it;
688 for (it = log_updater->log_list.begin(); it != log_updater->log_list.end(); it++)
690 if (it->logInfo.port_complete == port)
692 it->clear_logEntries();
696 log_updater->mutex.unlock();
701 if (log_updater ==
nullptr) {
705 log_updater->mutex.lock();
706 std::list<LogEntry>::iterator it;
707 for (it = log_updater->log_list.begin(); it != log_updater->log_list.end(); it++)
709 if (it->logInfo.port_complete == port)
712 if (it->last_read_message==-1)
716 if (from_beginning==
true)
718 it->last_read_message = 0;
720 int i=it->last_read_message;
721 int size = (int)it->entry_list.size();
724 messages.push_back(it->entry_list[i]);
726 it->last_read_message=i;
730 log_updater->mutex.unlock();
735 if (log_updater ==
nullptr) {
739 log_updater->mutex.lock();
740 std::list<LogEntry>::iterator it;
741 for (it = log_updater->log_list.begin(); it != log_updater->log_list.end(); it++)
743 if (it->logInfo.process_name == process)
746 if (it->last_read_message==-1)
750 if (from_beginning==
true)
752 it->last_read_message = 0;
754 int i=it->last_read_message;
755 for (; i<(int)it->entry_list.size(); i++)
757 messages.push_back(it->entry_list[i]);
759 it->last_read_message=i;
763 log_updater->mutex.unlock();
768 if (log_updater ==
nullptr) {
772 log_updater->mutex.lock();
773 std::list<LogEntry>::iterator it;
774 for (it = log_updater->log_list.begin(); it != log_updater->log_list.end(); it++)
776 if (it->logInfo.process_pid == pid)
779 if (it->last_read_message==-1)
783 if (from_beginning==
true)
785 it->last_read_message = 0;
787 int i=it->last_read_message;
788 for (; i<(int)it->entry_list.size(); i++)
790 messages.push_back(it->entry_list[i]);
792 it->last_read_message=i;
796 log_updater->mutex.unlock();
799const std::list<MessageEntry>
filter_by_level (
int level,
const std::list<MessageEntry>& messages)
801 std::list<MessageEntry>
ret;
802 std::list<MessageEntry>::const_iterator it;
803 for (it = messages.begin(); it != messages.end(); it++)
806 if (llevel.
toInt() == level) {
815 if (log_updater ==
nullptr) {
818 log_updater->mutex.lock();
819 if (logLevel ==
LOGLEVEL_UNDEFINED) {log_updater->listen_to_LOGLEVEL_UNDEFINED=enable;}
820 else if (logLevel ==
LOGLEVEL_TRACE) {log_updater->listen_to_LOGLEVEL_TRACE=enable;}
821 else if (logLevel ==
LOGLEVEL_INFO) {log_updater->listen_to_LOGLEVEL_INFO=enable;}
822 else if (logLevel ==
LOGLEVEL_DEBUG) {log_updater->listen_to_LOGLEVEL_DEBUG=enable;}
823 else if (logLevel ==
LOGLEVEL_WARNING) {log_updater->listen_to_LOGLEVEL_WARNING=enable;}
824 else if (logLevel ==
LOGLEVEL_ERROR) {log_updater->listen_to_LOGLEVEL_ERROR=enable;}
825 else if (logLevel ==
LOGLEVEL_FATAL) {log_updater->listen_to_LOGLEVEL_FATAL=enable;}
826 log_updater->mutex.unlock();
831 if (log_updater ==
nullptr) {
834 if (logLevel ==
LOGLEVEL_UNDEFINED) {
return log_updater->listen_to_LOGLEVEL_UNDEFINED;}
835 if (logLevel ==
LOGLEVEL_TRACE) {
return log_updater->listen_to_LOGLEVEL_TRACE;}
836 if (logLevel ==
LOGLEVEL_DEBUG) {
return log_updater->listen_to_LOGLEVEL_DEBUG;}
837 if (logLevel ==
LOGLEVEL_INFO) {
return log_updater->listen_to_LOGLEVEL_INFO;}
838 if (logLevel ==
LOGLEVEL_WARNING) {
return log_updater->listen_to_LOGLEVEL_WARNING;}
839 if (logLevel ==
LOGLEVEL_ERROR) {
return log_updater->listen_to_LOGLEVEL_ERROR;}
840 if (logLevel ==
LOGLEVEL_FATAL) {
return log_updater->listen_to_LOGLEVEL_FATAL;}
846 if (log_updater ==
nullptr) {
849 log_updater->mutex.lock();
850 log_updater->mutex.unlock();
860 if (log_updater ==
nullptr) {
863 log_updater->mutex.lock();
864 if (logSystem ==
LOGSYSTEM_YARP) {log_updater->listen_to_YARP_MESSAGES=enable;}
865 else if (logSystem ==
LOGSYSTEM_YARPRUN) {log_updater->listen_to_YARPRUN_MESSAGES=enable;}
866 log_updater->mutex.unlock();
871 if (log_updater ==
nullptr) {
874 if (logSystem ==
LOGSYSTEM_YARP) {
return log_updater->listen_to_YARP_MESSAGES;}
875 if (logSystem ==
LOGSYSTEM_YARPRUN) {
return log_updater->listen_to_YARPRUN_MESSAGES;}
881 if (log_updater ==
nullptr) {
885 log_updater->mutex.lock();
886 log_updater->logs_max_lines_enabled = enabled;
887 log_updater->logs_max_lines = new_size;
889 std::list<LogEntry>::iterator it;
890 for (it = log_updater->log_list.begin(); it != log_updater->log_list.end(); it++)
892 it->setLogEntryMaxSize(new_size);
893 it->setLogEntryMaxSizeEnabled(enabled);
896 log_updater->mutex.unlock();
902 if (log_updater ==
nullptr) {
905 log_updater->mutex.lock();
906 log_updater->log_list_max_size_enabled = enabled;
907 log_updater->log_list_max_size = new_size;
908 log_updater->mutex.unlock();
913 if (log_updater ==
nullptr) {
917 log_updater->mutex.lock();
918 enabled = log_updater->logs_max_lines_enabled;
919 current_size = log_updater->logs_max_lines;
920 log_updater->mutex.unlock();
925 if (log_updater ==
nullptr) {
928 log_updater->mutex.lock();
929 enabled=log_updater->log_list_max_size_enabled;
930 current_size=log_updater->log_list_max_size;
931 log_updater->mutex.unlock();
936 if (log_updater ==
nullptr) {
939 log_updater->mutex.lock();
940 log_updater->log_list.clear();
941 log_updater->mutex.unlock();
947 if (log_updater ==
nullptr) {
951 log_updater->mutex.lock();
952 std::list<LogEntry>::iterator it;
953 for (it = log_updater->log_list.begin(); it != log_updater->log_list.end(); it++)
955 if (it->logInfo.port_complete == port)
957 it->logging_enabled=enable;
961 log_updater->mutex.unlock();
966 if (log_updater ==
nullptr) {
971 log_updater->mutex.lock();
972 std::list<LogEntry>::iterator it;
973 for (it = log_updater->log_list.begin(); it != log_updater->log_list.end(); it++)
975 if (it->logInfo.port_complete == port)
977 enabled=it->logging_enabled;
981 log_updater->mutex.unlock();
const std::list< MessageEntry > filter_by_level(int level, const std::list< MessageEntry > &messages)
A simple collection of objects that can be described and transmitted in a portable way.
size_type size() const
Gets the number of elements in the bottle.
bool read(ConnectionReader &reader) override
Set the bottle's value based on input from a network connection.
Value & get(size_type index) const
Reads a Value v from a certain part of the list.
void addString(const char *str)
Places a string in the bottle, at the end of the list.
std::string toString() const override
Gives a human-readable textual representation of the bottle.
static std::string getNameServerName()
Get the name of the port associated with the nameserver (usually "/root", but this can be overwritten...
static bool connect(const std::string &src, const std::string &dest, const std::string &carrier="", bool quiet=true)
Request that an output port connect to an input port.
static Contact queryName(const std::string &name)
Find out information about a registered name.
static bool exists(const std::string &port, bool quiet=true, bool checkVer=true)
Check for a port to be ready and responsive.
An abstraction for a periodic thread.
A class for storing options and configuration information.
A port that is specialized as an RPC client.
static double nowSystem()
virtual bool isString() const
Checks if value is a string.
virtual Bottle * asList() const
Get list value.
std::string toString() const override
Return a standard text representation of the content of the object.
virtual std::string asString() const
Get string value.
void setNewError(LogLevel level)
std::string port_complete
yarp::yarpLogger::LogEntryInfo logInfo
void setLogEntryMaxSizeEnabled(bool enable)
bool append_logEntry(MessageEntry entry)
void setLogEntryMaxSize(int size)
std::vector< MessageEntry > entry_list
void set_log_list_max_size(bool enabled, int new_size)
bool get_listen_option(LogLevel logLevel)
void connect(const std::list< std::string > &ports)
void get_log_lines_max_size(bool &enabled, int ¤t_size)
void get_messages(std::list< MessageEntry > &messages)
bool get_log_enable_by_port_complete(std::string port)
void get_messages_by_port_prefix(std::string port, std::list< MessageEntry > &messages, bool from_beginning=false)
LoggerEngine(std::string portName)
void clear_messages_by_port_complete(std::string port)
void get_messages_by_port_complete(std::string port, std::list< MessageEntry > &messages, bool from_beginning=false)
void set_log_lines_max_size(bool enabled, int new_size)
void get_messages_by_process(std::string process, std::list< MessageEntry > &messages, bool from_beginning=false)
void discover(std::list< std::string > &ports)
void get_log_list_max_size(bool &enabled, int ¤t_size)
int get_num_of_processes()
void get_infos(std::list< LogEntryInfo > &infos)
void set_log_enable_by_port_complete(std::string port, bool enable)
void set_listen_option(LogLevel logLevel, bool enable)
void get_messages_by_pid(std::string pid, std::list< MessageEntry > &messages, bool from_beginning=false)
An interface to the operating system, including Port based communication.
std::string yarprun_timestamp
std::string local_timestamp