Просмотр исходного кода

GIB - Clean up log output and check for log histories even if basename does not include a date.

Ken Patel 16 лет назад
Родитель
Сommit
bc9a4e1db1
2 измененных файлов с 130 добавлено и 111 удалено
  1. 126 111
      direct/src/plugin/p3dMainObject.cxx
  2. 4 0
      direct/src/plugin/p3dMainObject.h

+ 126 - 111
direct/src/plugin/p3dMainObject.cxx

@@ -447,17 +447,14 @@ call_read_log(P3D_object *params[], int num_params) {
 ////////////////////////////////////////////////////////////////////
 //     Function: P3DMainObject::read_log
 //       Access: Private
-//  Description: The generic log-reader function.
+//  Description: log-reader meta function that handles reading
+//               previous log files in addition to the present one
 ////////////////////////////////////////////////////////////////////
 P3D_object *P3DMainObject::
 read_log(const string &log_pathname, P3D_object *params[], int num_params) {
   P3DInstanceManager *inst_mgr = P3DInstanceManager::get_global_ptr();
   string log_directory = inst_mgr->get_log_directory();
-
-  ifstream log(log_pathname.c_str(), ios::in);
-  if (!log) {
-    return inst_mgr->new_undefined_object();
-  }
+  ostringstream log_data;
 
   // Check the first parameter, if any--if given, it specifies the
   // last n bytes to retrieve.
@@ -465,57 +462,92 @@ read_log(const string &log_pathname, P3D_object *params[], int num_params) {
   if (num_params > 0) {
     tail_bytes = (size_t)max(P3D_OBJECT_GET_INT(params[0]), 0);
   }
-
   // Check the second parameter, if any--if given, it specifies the
   // first n bytes to retrieve.
   size_t head_bytes = 0;
   if (num_params > 1) {
     head_bytes = (size_t)max(P3D_OBJECT_GET_INT(params[1]), 0);
   }
-
-  // Check if we want data from previous logs
-  const char log_sep_line_char = '-';
-  const int log_sep_line_chars = 80;
-  const int log_sep_filename_chars = 256;
-  const int log_sep_bytes = log_sep_line_chars + log_sep_filename_chars + 16;
+  // Check the third parameter, if any--if given, it specifies the
+  // last n bytes to retrieve from previous copies of this file.
   size_t tail_bytes_prev = 0;
-  vector<string> log_basenames_prev;
   if (num_params > 2) {
-    // Determine the base of the log file names
     tail_bytes_prev = (size_t)max(P3D_OBJECT_GET_INT(params[2]), 0);
-    if (tail_bytes_prev > 0) {
-      string log_basename = log_pathname;
-      size_t slash = log_basename.rfind('/');
-      if (slash != string::npos) {
-        log_basename = log_basename.substr(slash + 1);
-      }
+  }
+
+  // Read the log data from the primary file
+  read_log_file(log_pathname, tail_bytes, head_bytes, log_data);
+
+  // Read data from previous logs if requested
+  if (tail_bytes_prev > 0) {
+    // Determine the base of the log file names
+    string log_basename = log_pathname;
+    size_t slash = log_basename.rfind('/');
+    if (slash != string::npos) {
+      log_basename = log_basename.substr(slash + 1);
+    }
 #ifdef _WIN32
-      slash = log_basename.rfind('\\');
-      if (slash != string::npos) {
-        log_basename = log_basename.substr(slash + 1);
-      }
+    slash = log_basename.rfind('\\');
+    if (slash != string::npos) {
+      log_basename = log_basename.substr(slash + 1);
+    }
 #endif  // _WIN32
-      string log_basename_curr = log_basename;
-      int dash = log_basename.rfind("-");
-      if (dash != string::npos) {
-        log_basename = log_basename.substr(0, dash+1);
-
-        // Find matching files
-        vector<string> all_logs;
-        inst_mgr->scan_directory(log_directory, all_logs);
-        for (int i=0; i<(int)all_logs.size(); ++i) {
-          if ((all_logs[i].size() > 4) &&
-              (all_logs[i].find(log_basename) == 0) &&
-              (all_logs[i].substr(all_logs[i].size() - 4) == string(".log"))) {
-            if (all_logs[i] != log_basename_curr) {
-              //log_basenames_prev.push_back(all_logs[i]);
-              //reverse order
-              log_basenames_prev.insert(log_basenames_prev.begin(), all_logs[i]);
-            }
-          }
-        }
+    string log_basename_primary = log_basename;
+    int dash = log_basename.rfind("-");
+    if (dash != string::npos) {
+      log_basename = log_basename.substr(0, dash+1);
+    } else {
+      int dotLog = log_basename.rfind(".log");
+      if (dotLog != string::npos) {
+        log_basename = log_basename.substr(0, dotLog);
+        log_basename += "-";
       }
     }
+
+    // Find matching files
+    vector<string> all_logs;
+    inst_mgr->scan_directory(log_directory, all_logs);
+    for (int i=(int)all_logs.size()-1; i>=0; --i) {
+      if ((all_logs[i].find(log_basename) == 0) &&
+          (all_logs[i] != log_basename_primary) && 
+          (all_logs[i].size() > 4) &&
+          (all_logs[i].substr(all_logs[i].size() - 4) == string(".log"))) {
+        read_log_file((log_directory+all_logs[i]), tail_bytes_prev, 0, log_data);
+      }
+    }
+  }
+
+  P3D_object *result = new P3DStringObject(log_data.str().c_str(), log_data.tellp());
+  return result;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: P3DMainObject::read_log_file
+//       Access: Private
+//  Description: The generic log-reader function.
+////////////////////////////////////////////////////////////////////
+void P3DMainObject::
+read_log_file(const string &log_pathname, 
+              size_t tail_bytes, size_t head_bytes, 
+              ostringstream &log_data) {
+  
+  // Get leaf name
+  string log_leafname = log_pathname;
+  size_t slash = log_leafname.rfind('/');
+  if (slash != string::npos) {
+    log_leafname = log_leafname.substr(slash + 1);
+  }
+#ifdef _WIN32
+  slash = log_leafname.rfind('\\');
+  if (slash != string::npos) {
+    log_leafname = log_leafname.substr(slash + 1);
+  }
+#endif  // _WIN32
+
+  // load file
+  ifstream log(log_pathname.c_str(), ios::in);
+  if (!log) {
+    return;
   }
 
   // Get the size of the file.
@@ -525,94 +557,77 @@ read_log(const string &log_pathname, P3D_object *params[], int num_params) {
        << " bytes, tail_bytes = " << tail_bytes << ", head_bytes = "
        << head_bytes << "\n";
 
-  size_t return_size = file_size;
-  string separator;
-
+  // Check if we are getting the full file
+  size_t full_bytes = 0;
   if (file_size <= head_bytes + tail_bytes) {
     // We will return the entire log.
-    head_bytes = file_size;
+    full_bytes = file_size;
+    head_bytes = 0;
     tail_bytes = 0;
-    return_size = file_size;
-
-  } else if (head_bytes == 0) {
-    // We will be returning the tail of the log only.
-    return_size = tail_bytes;
-
-  } else if (tail_bytes == 0) {
-    // We will be returning the head of the log only.
-    return_size = head_bytes;
-
-  } else {
-    // We will be excising the middle part of the log.
-    separator = "\n\n**** truncated ****\n\n";
-    return_size = head_bytes + separator.size() + tail_bytes;
   }
 
-  // We will need additional space for data from previous logs
-  if ((tail_bytes_prev > 0) && (log_basenames_prev.size() > 0)) {
-      int extra_bytes_per_prev_log = tail_bytes_prev + log_sep_bytes;
-      return_size += log_basenames_prev.size() * extra_bytes_per_prev_log;
+  // Allocate a temp buffer to hold file data
+  size_t buffer_bytes = full_bytes + head_bytes + tail_bytes + 1;
+  nout << "allocating " << buffer_bytes << " bytes to read from file.\n";
+  char *buffer = new char[buffer_bytes];
+  if (buffer == NULL) {
+    return;
   }
 
-  nout << "allocating " << return_size << " bytes to return.\n";
-  char *buffer = new char[return_size];
-  if (buffer == NULL) {
-    return NULL;
+  // Render log file header to log_data
+  log_data << "=======================================";
+  log_data << "=======================================" << "\n";
+  log_data << "== PandaLog-" << log_pathname << "\n";
+
+  // Render log data if full file is to be fetched
+  if (full_bytes > 0) {
+    log.seekg(0, ios::beg);
+    log.read(buffer, full_bytes);
+    buffer[log.gcount()] = NULL;
+    log_data << "== PandaLog-" << "Full Start";
+    log_data << " " << "(" << log_leafname << ")" << "\n";
+    log_data << buffer;
+    log_data << "== PandaLog-" << "Full End";
+    log_data << " " << "(" << log_leafname << ")" << "\n";
   }
 
-  char *bp = buffer;
+  // Render log data if head bytes are to be fetched
   if (head_bytes > 0) {
     log.seekg(0, ios::beg);
-    log.read(bp, head_bytes);
-    bp += log.gcount();
+    log.read(buffer, head_bytes);
+    buffer[log.gcount()] = NULL;
+    log_data << "== PandaLog-" << "Head Start";
+    log_data << " " << "(" << log_leafname << ")" << "\n";
+    log_data << buffer << "\n";
+    log_data << "== PandaLog-" << "Head End";
+    log_data << " " << "(" << log_leafname << ")" << "\n";
   }
 
-  if (!separator.empty()) {
-    memcpy(bp, separator.data(), separator.length());
-    bp += separator.length();
+  // Render separator if head & tail bytes are to be fetched
+  if ((head_bytes > 0) && (tail_bytes > 0)) {
+    log_data << "== PandaLog-" << "truncated";
+    log_data << " " << "(" << log_leafname << ")" << "\n";
   }
 
+  // Render log data if tail bytes are to be fetched
   if (tail_bytes > 0) {
     log.seekg(file_size - tail_bytes, ios::beg);
-    log.read(bp, tail_bytes);
-    bp += log.gcount();
+    log.read(buffer, tail_bytes);
+    buffer[log.gcount()] = NULL;
+    log_data << "== PandaLog-" << "Tail Start";
+    log_data << " " << "(" << log_leafname << ")" << "\n";
+    log_data << buffer;
+    log_data << "== PandaLog-" << "Tail End";
+    log_data << " " << "(" << log_leafname << ")" << "\n";
   }
 
-  // add data for previous logs
-  if ((tail_bytes_prev > 0) && (log_basenames_prev.size() > 0)) {
-    string log_sep_line = "\n";
-    for (int c=0; c<log_sep_line_chars; ++c) {
-        log_sep_line += log_sep_line_char;
-    }
-    log_sep_line += "\n";
-    for (int i=0; i<(int)log_basenames_prev.size(); ++i) {
-      ifstream log_prev((log_directory+log_basenames_prev[i]).c_str(), ios::in);
-      if (log_prev) {
-        // Insert file separator
-        string log_sep = "\n"+log_sep_line+log_basenames_prev[i]+log_sep_line+"\n";
-        assert(log_sep.length() <= (unsigned)log_sep_bytes); 
-        memcpy(bp, log_sep.data(), log_sep.length());
-        bp += log_sep.length();
-        // Insert prev file data
-        log_prev.seekg(0, ios::end);
-        size_t file_size = (size_t)log_prev.tellg();
-        size_t data_size = tail_bytes_prev;
-        if (data_size > file_size) {
-          data_size = file_size;
-        }
-        log_prev.seekg(file_size - data_size, ios::beg);
-        log_prev.read(bp, data_size);
-        bp += log_prev.gcount();
-      }
-    }
-  }
+  // Render log file footer to log_data
+  //log_data << "=======================================";
+  //log_data << "=======================================" << "\n";
 
-  assert(bp <= buffer + return_size);
-
-  P3D_object *result = new P3DStringObject(buffer, bp - buffer);
+  // cleanup
   delete[] buffer;
-  
-  return result;
+  buffer = NULL;
 }
 
 ////////////////////////////////////////////////////////////////////

+ 4 - 0
direct/src/plugin/p3dMainObject.h

@@ -18,6 +18,7 @@
 #include "p3d_plugin_common.h"
 #include "p3dObject.h"
 #include <map>
+#include <sstream>
 
 class P3DSession;
 class P3DInstance;
@@ -74,6 +75,9 @@ private:
   P3D_object *call_read_log(P3D_object *params[], int num_params);
   P3D_object *read_log(const string &log_pathname, 
                        P3D_object *params[], int num_params);
+  void        read_log_file(const string &log_pathname, 
+                            size_t tail_bytes, size_t head_bytes, 
+                            ostringstream &log_data);
   P3D_object *call_uninstall(P3D_object *params[], int num_params);
 
 private: