rosout_log_loader.cpp
Go to the documentation of this file.
00001 // *****************************************************************************
00002 //
00003 // Copyright (c) 2017, Southwest Research Institute® (SwRI®)
00004 // All rights reserved.
00005 //
00006 // Redistribution and use in source and binary forms, with or without
00007 // modification, are permitted provided that the following conditions are met:
00008 //     * Redistributions of source code must retain the above copyright
00009 //       notice, this list of conditions and the following disclaimer.
00010 //     * Redistributions in binary form must reproduce the above copyright
00011 //       notice, this list of conditions and the following disclaimer in the
00012 //       documentation and/or other materials provided with the distribution.
00013 //     * Neither the name of Southwest Research Institute® (SwRI®) nor the
00014 //       names of its contributors may be used to endorse or promote products
00015 //       derived from this software without specific prior written permission.
00016 //
00017 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
00018 // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00019 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00020 // ARE DISCLAIMED. IN NO EVENT SHALL Southwest Research Institute® BE LIABLE
00021 // FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00022 // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
00023 // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
00024 // CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00025 // LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
00026 // OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
00027 // DAMAGE.
00028 //
00029 // *****************************************************************************
00030 
00031 #include <QFileDialog>
00032 #include <QDir>
00033 #include <QDirIterator>
00034 
00035 #include <fstream>
00036 #include <ros/time.h>
00037 #include <rosbag/bag.h>
00038 #include <swri_console/rosout_log_loader.h>
00039 #include <time.h>
00040 #include <string>
00041 
00042 namespace swri_console
00043 {
00044   const int MIN_MSG_SIZE=10;
00045 
00046   void RosoutLogLoader::loadRosLogDirectory(const QString& logdirectory_name)
00047   {
00048     QDirIterator it(logdirectory_name, QStringList() << "*.log", QDir::Files);
00049     while (it.hasNext())
00050     {
00051         QString filename = it.next();
00052         printf("Loading log file %s ...\n", filename.toStdString().c_str());
00053         loadRosLog(filename);
00054     }
00055   }
00056 
00057   void RosoutLogLoader::loadRosLog(const QString& logfile_name)
00058   {
00059     std::string std_string_logfile = logfile_name.toStdString();
00060     std::ifstream logfile(std_string_logfile.c_str());
00061     int seq = 0;
00062     for( std::string line; getline( logfile, line ); )
00063     {
00064       rosgraph_msgs::Log log;
00065       unsigned found = std_string_logfile.find_last_of("/\\");
00066       log.name = std_string_logfile.substr(found+1);
00067       int result = parseLine(line, seq, &log);
00068       if (result == 0)
00069       {
00070         rosgraph_msgs::LogConstPtr log_ptr(new rosgraph_msgs::Log(log));
00071         emit logReceived(log_ptr);
00072       }
00073       seq++;
00074     }
00075     emit finishedReading();
00076   }
00077 
00078   int RosoutLogLoader::parseLine(std::string line, int seq, rosgraph_msgs::Log* log)
00079   {
00080     // Example: 1507066364.728102032 INFO [/home/pwesthart/code/src/mapviz/tile_map/src/tile_map_plugin.cpp:260(TileMapPlugin::PrintInfo) [topics: /rosout] OK
00081     char log_msg_fmt0[] = "%d.%d %s [%[^:]:%u(%[^)]) [topics: %[^]]] %[^\n]s";
00082     int secs = 0;
00083     int nsecs = 0;
00084     char level[16];
00085     char file[1024];
00086     unsigned int line_num = 1;
00087     char function[128];
00088     char topics[1024];
00089     char msg[1024*32];
00090     ros::Time stamp;
00091 
00093     int num_parsed = sscanf(line.c_str(),log_msg_fmt0,&secs, &nsecs, level, file, &line_num, function, topics, msg);
00094     if (num_parsed == 8 )
00095     {
00096       // Populate new log message
00097       log->file = file;
00098       log->function = function;
00099       log->header.seq = seq;
00100       stamp.sec = secs;
00101       stamp.nsec = nsecs;
00102       log->header.stamp = stamp;
00103       log->level = level_string_to_level_type(std::string(level));
00104       log->line = line_num;
00105       log->msg = msg;
00106     }
00107     else // try another format
00108     {
00109       char log_msg_fmt1[] = "%d.%d %s [%[^:]:%u(%[^)])) [topics: %[^]]] %[^\n]s";
00110       num_parsed = sscanf(line.c_str(), log_msg_fmt1, &secs, &nsecs, level, file, &line_num, function, topics, msg);
00111       if (num_parsed == 8 )
00112       {
00113         // Populate new log message
00114         log->file = file;
00115         log->function = function;
00116         log->header.seq = seq;
00117         stamp.sec = secs;
00118         stamp.nsec = nsecs;
00119         log->header.stamp = stamp;
00120         log->level = level_string_to_level_type(std::string(level));
00121         log->line = line_num;
00122         log->msg = msg;
00123       }
00124       else // try another format
00125       {
00126         // Example: [rospy.registration][INFO] 2017-11-30 08:11:39,231: registering subscriber topic [/tf] type [tf2_msgs/TFMessage] with master
00127         char log_msg_fmt2[] = "[%[^]]][%[^]]] %d-%d-%d %d:%d:%d,%d: %[^\n]s";
00128         int year;
00129         int month;
00130         int day;
00131         int hour;
00132         int minute;
00133         int msecs;
00134         char name[1024];
00135         time_t rawtime;
00136         struct tm * timeinfo;
00137 
00138         num_parsed = sscanf(line.c_str(), log_msg_fmt2, name, level, &year, &month, &day, &hour, &minute, &secs, &msecs, msg);
00139         if (num_parsed == 10)
00140         {
00141           // Populate new log message
00142           file[0] = 0;
00143           function[0] = 0;
00144           line_num = 0;
00145           time ( &rawtime );
00146           timeinfo = localtime ( &rawtime );
00147           timeinfo->tm_year = year - 1900;
00148           timeinfo->tm_mon = month - 1;
00149           timeinfo->tm_mday = day;
00150           timeinfo->tm_hour = hour;
00151           timeinfo->tm_min = minute;
00152           timeinfo->tm_sec = secs;
00153           rawtime = mktime ( timeinfo );
00154           secs = rawtime;
00155           nsecs = msecs * 1000000;
00156           log->file = file;
00157           log->function = function;
00158           log->header.seq = seq;
00159           stamp.sec = secs;
00160           stamp.nsec = nsecs;
00161           log->header.stamp = stamp;
00162           log->level = level_string_to_level_type(std::string(level));
00163           log->line = line_num;
00164           log->msg = msg;
00165         }
00166         else
00167         {
00168           // Example: [ INFO] [1512051098.518631473]: Read parameter lower_cost_threshold = 0.000000
00169           char log_msg_fmt3[] = "\x1b[%dm[ %[^]]] [%d.%d]: %[^\n\x1b]s";
00170 //          char log_msg_fmt3[] = "\x1b[%dm[ %[^]]] [%d.%d]]%[^\n]";
00171           int ansi_color;
00172           msg[0] = 0;
00173           num_parsed = sscanf(line.c_str(), log_msg_fmt3, &ansi_color, level, &secs, &nsecs, msg);
00174           if (num_parsed == 5)
00175           {
00176             // Populate new log message
00177             file[0] = 0;
00178             function[0] = 0;
00179             line_num = 0;
00180             log->file = file;
00181             log->function = function;
00182             log->header.seq = seq;
00183             stamp.sec = secs;
00184             stamp.nsec = nsecs;
00185             log->header.stamp = stamp;
00186             log->level = level_string_to_level_type(std::string(level));
00187             log->line = line_num;
00188             log->msg = msg;
00189           }
00190           else
00191           {
00192             // Example: [ WARN] [1512051107.153917534, 1507066358.521849475]: Offset change exceeds limit! reduce from 0.814476 to 0.500000
00193             char log_msg_fmt4[] = "\x1b[%dm[ %[^]]] [%d.%d, %d.%d]: %[^\n\x1b]";
00194             int secs2;
00195             int nsecs2;
00196             msg[0] = 0;
00197             num_parsed = sscanf(line.c_str(), log_msg_fmt4, &ansi_color, level, &secs, &nsecs, &secs2, &nsecs2, msg);
00198             if (num_parsed == 7)
00199             {
00200               // Populate new log message
00201               file[0] = 0;
00202               function[0] = 0;
00203               line_num = 0;
00204               log->file = file;
00205               log->function = function;
00206               log->header.seq = seq;
00207               stamp.sec = secs;
00208               stamp.nsec = nsecs;
00209               log->header.stamp = stamp;
00210               log->level = level_string_to_level_type(std::string(level));
00211               log->line = line_num;
00212               log->msg = msg;
00213             }
00214             else // Couldn't parse with known formats
00215             {
00216               if (line.length() < MIN_MSG_SIZE)
00217               {
00218                 return -1;
00219               }
00220               log->file = std::string("");
00221               log->function = std::string("");
00222               log->header.seq = seq;
00223               stamp.sec = 0;
00224               stamp.nsec = 0;
00225               log->header.stamp = stamp;
00226               log->level = level_string_to_level_type(std::string("DEBUG"));
00227               log->line = 0;
00228               log->msg = line;
00229               log->name = log->name + "-unparsed";
00230             }
00231           }
00232         }
00233       }
00234     }
00235     return 0;
00236   }
00237 
00238   rosgraph_msgs::Log::_level_type RosoutLogLoader::level_string_to_level_type(std::string level_str)
00239   {
00240     if (level_str.compare("FATAL") == 0)
00241     {
00242       return rosgraph_msgs::Log::FATAL;
00243     }
00244     if (level_str.compare("ERROR") == 0)
00245     {
00246       return rosgraph_msgs::Log::ERROR;
00247     }
00248     if (level_str.compare("WARN") == 0)
00249     {
00250       return rosgraph_msgs::Log::WARN;
00251     }
00252     if (level_str.compare("INFO") == 0)
00253     {
00254       return rosgraph_msgs::Log::INFO;
00255     }
00256     return rosgraph_msgs::Log::DEBUG;
00257   }
00258 
00259 
00260   void RosoutLogLoader::promptForLogFile()
00261   {
00262     QString filename = QFileDialog::getOpenFileName(NULL,
00263                                                     tr("Open ROS Log File"),
00264                                                     QDir::homePath(),
00265                                                     tr("Log Files (*.log)"));
00266 
00267     if (filename != NULL)
00268     {
00269       loadRosLog(filename);
00270     }
00271   }
00272 
00273   void RosoutLogLoader::promptForLogDirectory()
00274   {
00275     QString dirname = QFileDialog::getExistingDirectory(NULL,
00276                                                     tr("Open directory containing log files"),
00277                                                     QDir::homePath());
00278 
00279     if (dirname != NULL)
00280     {
00281       loadRosLogDirectory(dirname);
00282     }
00283   }
00284 
00285 
00286 }


swri_console
Author(s):
autogenerated on Sat Jun 8 2019 18:46:13