29 void LogEntry::clear_logEntries()
36 void LogEntry::setLogEntryMaxSize(
int size)
38 entry_list_max_size = size;
39 entry_list.reserve(entry_list_max_size);
43 void LogEntry::setLogEntryMaxSizeEnabled (
bool enable)
45 entry_list_max_size_enabled=enable;
50 if (logInfo.logsize >= entry_list_max_size && entry_list_max_size_enabled)
55 entry_list.push_back(entry);
60 void LogEntryInfo::clear()
78 void LogEntryInfo::clearLastError()
98 if (level > highest_error) {
99 highest_error = level;
103 void LoggerEngine::discover (std::list<std::string>& ports)
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++)
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();
184 void LoggerEngine::connect (
const std::list<std::string>& ports)
190 std::list<std::string>::const_iterator it;
191 for (it = ports.begin(); it != ports.end(); it++)
204 std::string LoggerEngine::logger_thread::getPortName()
206 return logger_portName;
211 logger_portName = _portname;
212 log_list_max_size = _log_list_max_size;
213 log_list_max_size_enabled =
true;
214 listen_to_LOGLEVEL_UNDEFINED =
true;
215 listen_to_LOGLEVEL_TRACE =
true;
216 listen_to_LOGLEVEL_DEBUG =
true;
217 listen_to_LOGLEVEL_INFO =
true;
218 listen_to_LOGLEVEL_WARNING =
true;
219 listen_to_LOGLEVEL_ERROR =
true;
220 listen_to_LOGLEVEL_FATAL =
true;
221 listen_to_YARP_MESSAGES =
true;
222 listen_to_YARPRUN_MESSAGES =
true;
223 unknown_format_received = 0;
226 void LoggerEngine::logger_thread::run()
236 int bufferport_size = logger_port.getPendingReads();
238 while (bufferport_size>0)
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();
375 if (p.check(
"systemtime")) {
376 body.
systemtime = p.find(
"systemtime").asFloat64();
381 if (p.check(
"networktime")) {
382 body.
networktime = p.find(
"networktime").asFloat64();
388 if (p.check(
"externaltime")) {
394 if (p.check(
"backtrace")) {
395 body.
backtrace = p.find(
"backtrace").asString();
406 size_t str = s.find(
'[',0);
407 size_t end = s.find(
']',0);
408 if (str==std::string::npos || end==std::string::npos )
414 std::string level = s.substr(str,end+1);
416 if (level.find(
"TRACE") != std::string::npos) {
418 }
else if (level.find(
"DEBUG") != std::string::npos) {
420 }
else if (level.find(
"INFO") != std::string::npos) {
422 }
else if (level.find(
"WARNING") != std::string::npos) {
424 }
else if (level.find(
"ERROR") != std::string::npos) {
426 }
else if (level.find(
"FATAL") != std::string::npos) {
429 body.
text = s.substr(end+1);
450 std::istringstream iss(header);
452 getline(iss, token,
'/');
460 if (entry.
logInfo.
port_system ==
"yarprunlog" && listen_to_YARPRUN_MESSAGES ==
false) {
464 std::list<LogEntry>::iterator it;
465 for (it = log_list.begin(); it != log_list.end(); it++)
469 if (it->logging_enabled)
471 it->logInfo.setNewError(body.
level);
472 it->logInfo.last_update=machine_current_time;
473 it->append_logEntry(body);
482 if (it == log_list.end())
484 if (log_list.size() < log_list_max_size || log_list_max_size_enabled==
false )
498 log_list.push_back(entry);
506 this->mutex.unlock();
517 fprintf(stderr,
"logger is already running, listening on port %s\n", log_updater->getPortName().c_str());
523 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());
527 if (log_updater->logger_port.open(log_updater->getPortName()))
529 fprintf(stdout,
"Logger successfully started, listening on port %s\n", log_updater->getPortName().c_str());
533 fprintf(stderr,
"Unable to start logger: port %s is unavailable\n", log_updater->getPortName().c_str());
536 log_updater->logger_port.resume();
537 log_updater->logger_port.setStrict();
539 log_updater->start();
543 void LoggerEngine::logger_thread::threadRelease()
545 logger_port.interrupt();
551 if (log_updater ==
nullptr) {
556 if (log_updater->isRunning() ==
true) {
564 if (log_updater ==
nullptr) {
568 log_updater->start();
579 log_updater=
new logger_thread (portName, 0.01);
587 if (log_updater!=
nullptr)
590 log_updater =
nullptr;
596 if (log_updater ==
nullptr) {
600 return log_updater->logger_port.getInputCount();
605 if (log_updater ==
nullptr) {
609 log_updater->mutex.lock();
610 std::list<LogEntry>::iterator it;
611 for (it = log_updater->log_list.begin(); it != log_updater->log_list.end(); it++)
613 infos.push_back(it->logInfo);
615 log_updater->mutex.unlock();
620 if (log_updater ==
nullptr) {
624 log_updater->mutex.lock();
625 std::list<LogEntry>::iterator it;
626 for (it = log_updater->log_list.begin(); it != log_updater->log_list.end(); it++)
628 messages.insert(messages.end(), it->entry_list.begin(), it->entry_list.end());
630 log_updater->mutex.unlock();
635 if (log_updater ==
nullptr) {
639 log_updater->mutex.lock();
640 std::list<LogEntry>::iterator it;
641 for (it = log_updater->log_list.begin(); it != log_updater->log_list.end(); it++)
643 if (it->logInfo.port_prefix == port)
646 if (it->last_read_message==-1)
650 if (from_beginning==
true)
652 it->last_read_message = 0;
654 int i=it->last_read_message;
655 for (; i<(int)it->entry_list.size(); i++)
657 messages.push_back(it->entry_list[i]);
659 it->last_read_message=i;
663 log_updater->mutex.unlock();
668 if (log_updater ==
nullptr) {
672 log_updater->mutex.lock();
673 std::list<LogEntry>::iterator it;
674 for (it = log_updater->log_list.begin(); it != log_updater->log_list.end(); it++)
676 if (it->logInfo.port_complete == port)
678 it->clear_logEntries();
682 log_updater->mutex.unlock();
687 if (log_updater ==
nullptr) {
691 log_updater->mutex.lock();
692 std::list<LogEntry>::iterator it;
693 for (it = log_updater->log_list.begin(); it != log_updater->log_list.end(); it++)
695 if (it->logInfo.port_complete == port)
698 if (it->last_read_message==-1)
702 if (from_beginning==
true)
704 it->last_read_message = 0;
706 int i=it->last_read_message;
707 int size = (int)it->entry_list.size();
710 messages.push_back(it->entry_list[i]);
712 it->last_read_message=i;
716 log_updater->mutex.unlock();
721 if (log_updater ==
nullptr) {
725 log_updater->mutex.lock();
726 std::list<LogEntry>::iterator it;
727 for (it = log_updater->log_list.begin(); it != log_updater->log_list.end(); it++)
729 if (it->logInfo.process_name == process)
732 if (it->last_read_message==-1)
736 if (from_beginning==
true)
738 it->last_read_message = 0;
740 int i=it->last_read_message;
741 for (; i<(int)it->entry_list.size(); i++)
743 messages.push_back(it->entry_list[i]);
745 it->last_read_message=i;
749 log_updater->mutex.unlock();
754 if (log_updater ==
nullptr) {
758 log_updater->mutex.lock();
759 std::list<LogEntry>::iterator it;
760 for (it = log_updater->log_list.begin(); it != log_updater->log_list.end(); it++)
762 if (it->logInfo.process_pid == pid)
765 if (it->last_read_message==-1)
769 if (from_beginning==
true)
771 it->last_read_message = 0;
773 int i=it->last_read_message;
774 for (; i<(int)it->entry_list.size(); i++)
776 messages.push_back(it->entry_list[i]);
778 it->last_read_message=i;
782 log_updater->mutex.unlock();
785 const std::list<MessageEntry>
filter_by_level (
int level,
const std::list<MessageEntry>& messages)
787 std::list<MessageEntry>
ret;
788 std::list<MessageEntry>::const_iterator it;
789 for (it = messages.begin(); it != messages.end(); it++)
792 if (llevel.
toInt() == level) {
801 if (log_updater ==
nullptr) {
804 log_updater->mutex.lock();
805 if (logLevel ==
LOGLEVEL_UNDEFINED) {log_updater->listen_to_LOGLEVEL_UNDEFINED=enable;}
806 else if (logLevel ==
LOGLEVEL_TRACE) {log_updater->listen_to_LOGLEVEL_TRACE=enable;}
807 else if (logLevel ==
LOGLEVEL_INFO) {log_updater->listen_to_LOGLEVEL_INFO=enable;}
808 else if (logLevel ==
LOGLEVEL_DEBUG) {log_updater->listen_to_LOGLEVEL_DEBUG=enable;}
809 else if (logLevel ==
LOGLEVEL_WARNING) {log_updater->listen_to_LOGLEVEL_WARNING=enable;}
810 else if (logLevel ==
LOGLEVEL_ERROR) {log_updater->listen_to_LOGLEVEL_ERROR=enable;}
811 else if (logLevel ==
LOGLEVEL_FATAL) {log_updater->listen_to_LOGLEVEL_FATAL=enable;}
812 log_updater->mutex.unlock();
817 if (log_updater ==
nullptr) {
820 if (logLevel ==
LOGLEVEL_UNDEFINED) {
return log_updater->listen_to_LOGLEVEL_UNDEFINED;}
821 if (logLevel ==
LOGLEVEL_TRACE) {
return log_updater->listen_to_LOGLEVEL_TRACE;}
822 if (logLevel ==
LOGLEVEL_DEBUG) {
return log_updater->listen_to_LOGLEVEL_DEBUG;}
823 if (logLevel ==
LOGLEVEL_INFO) {
return log_updater->listen_to_LOGLEVEL_INFO;}
824 if (logLevel ==
LOGLEVEL_WARNING) {
return log_updater->listen_to_LOGLEVEL_WARNING;}
825 if (logLevel ==
LOGLEVEL_ERROR) {
return log_updater->listen_to_LOGLEVEL_ERROR;}
826 if (logLevel ==
LOGLEVEL_FATAL) {
return log_updater->listen_to_LOGLEVEL_FATAL;}
832 if (log_updater ==
nullptr) {
835 log_updater->mutex.lock();
836 log_updater->mutex.unlock();
846 if (log_updater ==
nullptr) {
849 log_updater->mutex.lock();
850 if (logSystem ==
LOGSYSTEM_YARP) {log_updater->listen_to_YARP_MESSAGES=enable;}
851 else if (logSystem ==
LOGSYSTEM_YARPRUN) {log_updater->listen_to_YARPRUN_MESSAGES=enable;}
852 log_updater->mutex.unlock();
857 if (log_updater ==
nullptr) {
860 if (logSystem ==
LOGSYSTEM_YARP) {
return log_updater->listen_to_YARP_MESSAGES;}
861 if (logSystem ==
LOGSYSTEM_YARPRUN) {
return log_updater->listen_to_YARPRUN_MESSAGES;}
867 if (log_updater ==
nullptr) {
870 if (filename.size() == 0) {
874 log_updater->mutex.lock();
875 std::list<LogEntry>::iterator it;
876 for (it = log_updater->log_list.begin(); it != log_updater->log_list.end(); it++)
878 if (it->logInfo.port_complete == portname)
881 file1.open(filename.c_str());
882 if (file1.is_open() ==
false) {log_updater->mutex.unlock();
return false;}
883 std::vector<MessageEntry>::iterator it1;
884 for (it1 = it->entry_list.begin(); it1 != it->entry_list.end(); it1++)
886 file1 << it1->yarprun_timestamp <<
" " << it1->local_timestamp <<
" " << it1->level.toString() <<
" " << it1->text <<
'\n';
891 log_updater->mutex.unlock();
897 std::string start_string =
"<#STRING_START#>";
898 std::string end_string =
"<#STRING_END#>";
900 if (log_updater ==
nullptr) {
903 if (filename.size() == 0) {
907 const int LOGFILE_VERSION = 1;
910 file1.open(filename.c_str());
911 if (file1.is_open() ==
false) {
915 bool wasRunning = log_updater->isRunning();
919 std::list<LogEntry>::iterator it;
920 file1 << LOGFILE_VERSION <<
'\n';
921 file1 << log_updater->log_list.size() <<
'\n';
922 for (it = log_updater->log_list.begin(); it != log_updater->log_list.end(); it++)
924 file1 << it->logInfo.ip_address <<
'\n';
925 file1 << it->logInfo.port_complete <<
'\n';
926 file1 << it->logInfo.port_prefix <<
'\n';
927 file1 << it->logInfo.port_system <<
'\n';
928 file1 << it->logInfo.process_name <<
'\n';
929 file1 << it->logInfo.process_pid <<
'\n';
930 file1 << it->logInfo.get_number_of_traces() <<
'\n';
931 file1 << it->logInfo.get_number_of_debugs() <<
'\n';
932 file1 << it->logInfo.get_number_of_infos() <<
'\n';
933 file1 << it->logInfo.get_number_of_warnings() <<
'\n';
934 file1 << it->logInfo.get_number_of_errors() <<
'\n';
935 file1 << it->logInfo.get_number_of_fatals() <<
'\n';
936 file1 << it->logInfo.logsize <<
'\n';
937 file1 << it->entry_list.size() <<
'\n';
938 std::vector<MessageEntry>::iterator it1;
939 for (it1 = it->entry_list.begin(); it1 != it->entry_list.end(); it1++)
941 file1 << it1->yarprun_timestamp <<
'\n';
942 file1 << it1->local_timestamp <<
'\n';
943 file1 << it1->level.toInt() <<
'\n';
944 file1 << start_string;
945 for (
char s : it1->text) {
948 file1 << end_string <<
'\n';
953 log_updater->start();
958 std::streamoff
get_tag(std::ifstream& file,
const char* tag)
960 std::streamoff pos=file.tellg();
961 int tag_size=strlen(tag);
962 char* buff =
new char[tag_size+2];
963 for (
int i = 0; i < tag_size + 2; i++) {
966 std::streamoff off=0;
970 file.read(buff,tag_size);
971 if (file.good()==
false)
976 if (strcmp(buff, tag) == 0) {
986 std::string start_string =
"<#STRING_START#>";
987 int start_string_size=strlen(start_string.c_str());
988 std::string end_string =
"<#STRING_END#>";
989 int end_string_size=strlen(end_string.c_str());
991 if (log_updater ==
nullptr) {
994 if (filename.size() == 0) {
998 const int LOGFILE_VERSION = 1;
1000 std::ifstream file1;
1001 file1.open(filename.c_str(),std::ifstream::binary);
1002 if (file1.is_open() ==
false) {
1006 int log_file_version;
1007 bool wasRunning = log_updater->isRunning();
1009 log_updater->stop();
1011 file1 >> log_file_version;
1012 if (log_file_version == LOGFILE_VERSION)
1015 file1 >> size_log_list;
1016 log_updater->log_list.clear();
1017 for (
int i=0; i< size_log_list; i++)
1034 int size_entry_list;
1035 file1 >> size_entry_list;
1036 for (
int j=0; j< size_entry_list; j++)
1044 std::streamoff start_p =
get_tag(file1, start_string.c_str());
1045 std::streamoff end_p =
get_tag(file1, end_string.c_str());
1047 if (start_p < 0 || end_p < 0 || end_p - start_p + start_string_size <= 0) {
1050 char *buff =
new char[(
unsigned int)(end_p-start_p+start_string_size)];
1052 file1.seekg(start_p+start_string_size);
1053 if (end_p-start_p-start_string_size!=1)
1055 file1.get(buff,end_p-start_p-start_string_size);
1061 file1.seekg(end_p+end_string_size);
1066 log_updater->log_list.push_back(l_tmp);
1071 log_updater->start();
1078 if (log_updater ==
nullptr) {
1081 log_updater->mutex.lock();
1083 std::list<LogEntry>::iterator it;
1084 for (it = log_updater->log_list.begin(); it != log_updater->log_list.end(); it++)
1086 it->setLogEntryMaxSize(new_size);
1087 it->setLogEntryMaxSizeEnabled(enabled);
1090 log_updater->mutex.unlock();
1096 if (log_updater ==
nullptr) {
1099 log_updater->mutex.lock();
1100 log_updater->log_list_max_size_enabled = enabled;
1101 log_updater->log_list_max_size = new_size;
1102 log_updater->mutex.unlock();
1107 if (log_updater ==
nullptr) {
1110 if (log_updater->log_list.empty() ==
true) {
1113 log_updater->mutex.lock();
1114 auto it = log_updater->log_list.begin();
1115 current_size = it->getLogEntryMaxSize();
1116 enabled = it->getLogEntryMaxSizeEnabled();
1117 log_updater->mutex.unlock();
1122 if (log_updater ==
nullptr) {
1125 log_updater->mutex.lock();
1126 enabled=log_updater->log_list_max_size_enabled;
1127 current_size=log_updater->log_list_max_size;
1128 log_updater->mutex.unlock();
1133 if (log_updater ==
nullptr) {
1136 log_updater->mutex.lock();
1137 log_updater->log_list.clear();
1138 log_updater->mutex.unlock();
1144 if (log_updater ==
nullptr) {
1148 log_updater->mutex.lock();
1149 std::list<LogEntry>::iterator it;
1150 for (it = log_updater->log_list.begin(); it != log_updater->log_list.end(); it++)
1152 if (it->logInfo.port_complete == port)
1154 it->logging_enabled=enable;
1158 log_updater->mutex.unlock();
1163 if (log_updater ==
nullptr) {
1168 log_updater->mutex.lock();
1169 std::list<LogEntry>::iterator it;
1170 for (it = log_updater->log_list.begin(); it != log_updater->log_list.end(); it++)
1172 if (it->logInfo.port_complete == port)
1174 enabled=it->logging_enabled;
1178 log_updater->mutex.unlock();
std::streamoff get_tag(std::ifstream &file, const char *tag)
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
bool append_logEntry(MessageEntry entry)
std::vector< MessageEntry > entry_list
void setLevel(LogLevelEnum level)
void set_log_list_max_size(bool enabled, int new_size)
bool get_listen_option(LogLevel logLevel)
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)
bool load_all_logs_from_file(std::string filename)
void get_log_list_max_size(bool &enabled, int ¤t_size)
int get_num_of_processes()
bool save_all_logs_to_file(std::string filename)
bool export_log_to_text_file(std::string filename, std::string portname)
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