mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-03 10:22:45 -04:00
implement log_history functionality
This commit is contained in:
parent
d18f226684
commit
8dc84e42d8
@ -450,9 +450,11 @@ call_read_log(P3D_object *params[], int num_params) {
|
|||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
P3D_object *P3DMainObject::
|
P3D_object *P3DMainObject::
|
||||||
read_log(const string &log_pathname, P3D_object *params[], int num_params) {
|
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);
|
ifstream log(log_pathname.c_str(), ios::in);
|
||||||
if (!log) {
|
if (!log) {
|
||||||
P3DInstanceManager *inst_mgr = P3DInstanceManager::get_global_ptr();
|
|
||||||
return inst_mgr->new_undefined_object();
|
return inst_mgr->new_undefined_object();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -470,6 +472,49 @@ read_log(const string &log_pathname, P3D_object *params[], int num_params) {
|
|||||||
head_bytes = (size_t)max(P3D_OBJECT_GET_INT(params[1]), 0);
|
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;
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
#ifdef _WIN32
|
||||||
|
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]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Get the size of the file.
|
// Get the size of the file.
|
||||||
log.seekg(0, ios::end);
|
log.seekg(0, ios::end);
|
||||||
size_t file_size = (size_t)log.tellg();
|
size_t file_size = (size_t)log.tellg();
|
||||||
@ -500,6 +545,12 @@ read_log(const string &log_pathname, P3D_object *params[], int num_params) {
|
|||||||
return_size = head_bytes + separator.size() + tail_bytes;
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
nout << "allocating " << return_size << " bytes to return.\n";
|
nout << "allocating " << return_size << " bytes to return.\n";
|
||||||
char *buffer = new char[return_size];
|
char *buffer = new char[return_size];
|
||||||
if (buffer == NULL) {
|
if (buffer == NULL) {
|
||||||
@ -524,11 +575,40 @@ read_log(const string &log_pathname, P3D_object *params[], int num_params) {
|
|||||||
bp += log.gcount();
|
bp += log.gcount();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
assert(bp <= buffer + return_size);
|
assert(bp <= buffer + return_size);
|
||||||
|
|
||||||
P3D_object *result = new P3DStringObject(buffer, bp - buffer);
|
P3D_object *result = new P3DStringObject(buffer, bp - buffer);
|
||||||
delete[] buffer;
|
delete[] buffer;
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -29,6 +29,7 @@
|
|||||||
#include "run_p3dpython.h"
|
#include "run_p3dpython.h"
|
||||||
|
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
|
#include <time.h>
|
||||||
|
|
||||||
#ifndef _WIN32
|
#ifndef _WIN32
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
@ -1019,6 +1020,49 @@ start_p3dpython(P3DInstance *inst) {
|
|||||||
}
|
}
|
||||||
#endif // _WIN32
|
#endif // _WIN32
|
||||||
|
|
||||||
|
// Check if we want to keep copies of recent logs on disk.
|
||||||
|
// Get the log history count from the HTML tokens, or from the
|
||||||
|
// p3d_info.xml file.
|
||||||
|
int log_history = inst->get_fparams().lookup_token_int("log_history");
|
||||||
|
if (!log_basename.empty() && (log_history > 1)) {
|
||||||
|
// Append suffix separator
|
||||||
|
log_basename += "-";
|
||||||
|
|
||||||
|
// Delete all but the most recent 'log_history' logs
|
||||||
|
vector<string> all_logs;
|
||||||
|
vector<string> matching_logs;
|
||||||
|
string log_directory = inst_mgr->get_log_directory();
|
||||||
|
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"))) {
|
||||||
|
matching_logs.push_back((log_directory + all_logs[i]));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (int i=0; i<(int)matching_logs.size()-log_history; ++i) {
|
||||||
|
unlink(matching_logs[i].c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Append a timestamp suffix to the log_basename
|
||||||
|
_tzset();
|
||||||
|
time_t log_time_seconds = time(NULL);
|
||||||
|
struct tm *log_time_local_p = localtime(&log_time_seconds);
|
||||||
|
if (log_time_local_p != NULL) {
|
||||||
|
struct tm log_time_local = *log_time_local_p;
|
||||||
|
static const size_t buffer_size = 16;
|
||||||
|
char buffer[buffer_size];
|
||||||
|
sprintf(buffer, "%02d%02d%02d_%02d%02d%02d",
|
||||||
|
(int)(log_time_local.tm_year+1900-2000),
|
||||||
|
(int)(log_time_local.tm_mon),
|
||||||
|
(int)(log_time_local.tm_mday),
|
||||||
|
(int)(log_time_local.tm_hour),
|
||||||
|
(int)(log_time_local.tm_min),
|
||||||
|
(int)(log_time_local.tm_sec));
|
||||||
|
log_basename += buffer;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (!console_output && !log_basename.empty()) {
|
if (!console_output && !log_basename.empty()) {
|
||||||
_log_pathname = inst_mgr->get_log_directory();
|
_log_pathname = inst_mgr->get_log_directory();
|
||||||
_log_pathname += log_basename;
|
_log_pathname += log_basename;
|
||||||
|
@ -120,7 +120,10 @@ extern "C" {
|
|||||||
written. Otherwise, the compiled-in default is used; if there is
|
written. Otherwise, the compiled-in default is used; if there is
|
||||||
no compiled-in default, no logfile output will be generated by the
|
no compiled-in default, no logfile output will be generated by the
|
||||||
core API. Note that the individual instances also have their own
|
core API. Note that the individual instances also have their own
|
||||||
log_basename values.
|
log_basename values. If log_history is greater than zero, the
|
||||||
|
most recent log_history (count) logs generated (per log_basename)
|
||||||
|
will be retained on disk, each named uniquely by appending a
|
||||||
|
timestamp to the log_basename before file creation.
|
||||||
|
|
||||||
Next, trusted_environment should be set true to indicate that the
|
Next, trusted_environment should be set true to indicate that the
|
||||||
environment and p3d file are already trusted. If this is set, the
|
environment and p3d file are already trusted. If this is set, the
|
||||||
|
Loading…
x
Reference in New Issue
Block a user