Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions include/tscore/Diags.h
Original file line number Diff line number Diff line change
Expand Up @@ -219,6 +219,7 @@ class Diags
bool setup_diagslog(BaseLogFile *blf);
void config_roll_diagslog(RollingEnabledValues re, int ri, int rs);
void config_roll_outputlog(RollingEnabledValues re, int ri, int rs);
bool reseat_diagslog();
bool should_roll_diagslog();
bool should_roll_outputlog();

Expand Down
6 changes: 6 additions & 0 deletions proxy/logging/Log.cc
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,12 @@ Log::change_configuration()
Debug("log-config", "... new configuration in place");
}

void
Log::reopen_moved_log_files()
{
Log::config->log_object_manager.reopen_moved_log_files();
}

/*-------------------------------------------------------------------------
PERIODIC EVENTS

Expand Down
8 changes: 8 additions & 0 deletions proxy/logging/Log.h
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,14 @@ class Log

// reconfiguration stuff
static void change_configuration();

/** Check each log file path to see whether it exists and re-open if not.
*
* This is called when an external log rotation entity has moved log files to
* rolled names. This checks whether the original log file exists and, if
* not, closes the file descriptor and re-opens the file.
*/
static void reopen_moved_log_files();
static int handle_logging_mode_change(const char *name, RecDataT data_type, RecData data, void *cookie);
static int handle_periodic_tasks_int_change(const char *name, RecDataT data_type, RecData data, void *cookie);

Expand Down
29 changes: 29 additions & 0 deletions proxy/logging/LogFile.cc
Original file line number Diff line number Diff line change
Expand Up @@ -391,6 +391,35 @@ LogFile::roll(long interval_start, long interval_end, bool reopen_after_rolling)
return 0;
}

/*-------------------------------------------------------------------------
LogFile::reopen_if_moved

Check whether the file at the log's filename exists and, if not, close
the current file descriptor and reopen it. This function can be used to
facilitate external log rotation mechanisms which will move the original
file to a rolled filename. Logging will happen to that same file
descriptor until this function is called, at which point the non-existent
original file will be detected, the file descriptor will be closed, and
the log file will be re-opened.

Returns True if the file was re-opened, false otherwise.
-------------------------------------------------------------------------*/
bool
LogFile::reopen_if_moved()
{
if (!m_name) {
return false;
}
if (LogFile::exists(m_name)) {
return false;
}

// Both of the following log if there are problems.
close_file();
open_file();
return true;
}

/*-------------------------------------------------------------------------
LogFile::preproc_and_try_delete

Expand Down
7 changes: 7 additions & 0 deletions proxy/logging/LogFile.h
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,13 @@ class LogFile : public LogBufferSink, public RefCountObj
bool trim_rolled(size_t rolling_max_count);
int roll(long interval_start, long interval_end, bool reopen_after_rolling = false);

/** Check whether the file at the log's filename exists and, if not, close
* the current file descriptor and reopen it.
*
* @return True if the file was re-opened, false otherwise.
*/
bool reopen_if_moved();

const char *
get_name() const
{
Expand Down
16 changes: 16 additions & 0 deletions proxy/logging/LogObject.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1241,6 +1241,22 @@ LogObjectManager::roll_files(long time_now)
return num_rolled;
}

void
LogObjectManager::reopen_moved_log_files()
{
for (auto &_object : this->_objects) {
_object->m_logFile->reopen_if_moved();
}

ACQUIRE_API_MUTEX("A LogObjectManager::reopen_moved_log_files");

for (auto &_APIobject : this->_APIobjects) {
_APIobject->m_logFile->reopen_if_moved();
}

RELEASE_API_MUTEX("R LogObjectManager::reopen_moved_log_files");
}

void
LogObjectManager::display(FILE *str)
{
Expand Down
1 change: 1 addition & 0 deletions proxy/logging/LogObject.h
Original file line number Diff line number Diff line change
Expand Up @@ -388,6 +388,7 @@ class LogObjectManager
void check_buffer_expiration(long time_now);

unsigned roll_files(long time_now);
void reopen_moved_log_files();

int log(LogAccess *lad);
void display(FILE *str = stdout);
Expand Down
32 changes: 24 additions & 8 deletions src/traffic_manager/traffic_manager.cc
Original file line number Diff line number Diff line change
Expand Up @@ -83,14 +83,14 @@ extern "C" int getpwnam_r(const char *name, struct passwd *result, char *buffer,

static AppVersionInfo appVersionInfo; // Build info for this application

static inkcoreapi DiagsConfig *diagsConfig;
static char debug_tags[1024] = "";
static char action_tags[1024] = "";
static int proxy_off = false;
static int listen_off = false;
static char bind_stdout[512] = "";
static char bind_stderr[512] = "";
static const char *mgmt_path = nullptr;
static inkcoreapi DiagsConfig *diagsConfig = nullptr;
static char debug_tags[1024] = "";
static char action_tags[1024] = "";
static int proxy_off = false;
static int listen_off = false;
static char bind_stdout[512] = "";
static char bind_stderr[512] = "";
static const char *mgmt_path = nullptr;

// By default, set the current directory as base
static const char *recs_conf = ts::filename::RECORDS;
Expand Down Expand Up @@ -923,6 +923,22 @@ SignalHandler(int sig)
return;
}

if (sig == SIGUSR2) {
fprintf(stderr, "[TrafficManager] ==> received SIGUSR2, rotating the logs.\n");
mgmt_log("[TrafficManager] ==> received SIGUSR2, rotating the logs.\n");
if (lmgmt && lmgmt->watched_process_pid != -1) {
kill(lmgmt->watched_process_pid, sig);
}
diags->set_std_output(StdStream::STDOUT, bind_stdout);
diags->set_std_output(StdStream::STDERR, bind_stderr);
if (diags->reseat_diagslog()) {
Note("Reseated %s", DIAGS_LOG_FILENAME);
} else {
Note("Could not reseat %s", DIAGS_LOG_FILENAME);
}
return;
}

fprintf(stderr, "[TrafficManager] ==> Cleaning up and reissuing signal #%d\n", sig);
mgmt_log("[TrafficManager] ==> Cleaning up and reissuing signal #%d\n", sig);

Expand Down
8 changes: 7 additions & 1 deletion src/traffic_server/traffic_server.cc
Original file line number Diff line number Diff line change
Expand Up @@ -281,10 +281,16 @@ class SignalContinuation : public Continuation
signal_received[SIGUSR2] = false;

Debug("log", "received SIGUSR2, reloading traffic.out");

// reload output logfile (file is usually called traffic.out)
diags->set_std_output(StdStream::STDOUT, bind_stdout);
diags->set_std_output(StdStream::STDERR, bind_stderr);
if (diags->reseat_diagslog()) {
Note("Reseated %s", DIAGS_LOG_FILENAME);
} else {
Note("Could not reseat %s", DIAGS_LOG_FILENAME);
}
// Reload any of the other moved log files (such as the ones in logging.yaml).
Log::reopen_moved_log_files();
}

if (signal_received[SIGTERM] || signal_received[SIGINT]) {
Expand Down
34 changes: 34 additions & 0 deletions src/tscore/Diags.cc
Original file line number Diff line number Diff line change
Expand Up @@ -516,6 +516,40 @@ Diags::config_roll_outputlog(RollingEnabledValues re, int ri, int rs)
outputlog_rolling_size = rs;
}

/*
* Update diags_log to use the underlying file on disk.
*
* This function will replace the current BaseLogFile object with a new one, as
* each BaseLogFile object logically represents one file on disk. It can be
* used when we want to re-open the log file if the initial one was moved.
*
* Note that, however, cross process race conditions may still exist,
* especially with the metafile, and further work with flock() for fcntl() may
* still need to be done.
*
* Returns true if the log was reseated, false otherwise.
*/
bool
Diags::reseat_diagslog()
{
if (diags_log == nullptr || !diags_log->is_init()) {
return false;
}
fflush(diags_log->m_fp);
char *oldname = ats_strdup(diags_log->get_name());
log_log_trace("in %s for diags.log, oldname=%s\n", __func__, oldname);
BaseLogFile *n = new BaseLogFile(oldname);
if (setup_diagslog(n)) {
BaseLogFile *old_diags = diags_log;
lock();
diags_log = n;
unlock();
delete old_diags;
}
ats_free(oldname);
return true;
}

/*
* Checks diags_log 's underlying file on disk and see if it needs to be rolled,
* and does so if necessary.
Expand Down
5 changes: 5 additions & 0 deletions tests/gold_tests/autest-site/trafficserver.test.ext
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,11 @@ def MakeATSProcess(obj, name, command='traffic_server', select_ports=True,
p.Disk.diags_log.Content += Testers.ExcludesExpression(
"FATAL:", "diags.log should not contain errors")

if command == "traffic_manager":
fname = "manager.log"
tmpname = os.path.join(log_dir, fname)
p.Disk.File(tmpname, id=make_id(fname))

# config files
def MakeConfigFile(self, fname):
tmpname = os.path.join(config_dir, fname)
Expand Down
Loading