blob: 9b0e098c62dfd9faed6514c5996a5205fae4e106 [file] [log] [blame]
///////////////////////////////////////////////////////////////////////////////
//
// @@@ START COPYRIGHT @@@
//
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
//
// @@@ END COPYRIGHT @@@
//
///////////////////////////////////////////////////////////////////////////////
using namespace std;
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <mpi.h>
#include "msgdef.h"
#include "montrace.h"
extern int MyPNID;
extern char Node_name[MPI_MAX_PROCESSOR_NAME];
const char *CMonTrace::str_trace_enable = "MON_TRACE_ENABLE";
const char *CMonTrace::str_trace_file = "MON_TRACE_FILE";
const char *CMonTrace::str_trace_file_fb = "MON_TRACE_FILE_FB";
const CMonTrace::traceArea CMonTrace::traceAreaList[] =
{ {"MON_TRACE_REQUEST", TRACE_REQUEST},
{"MON_TRACE_REQUEST_DETAIL", TRACE_REQUEST_DETAIL},
{"MON_TRACE_PROCESS", TRACE_PROCESS},
{"MON_TRACE_PROCESS_DETAIL", TRACE_PROCESS_DETAIL},
{"MON_TRACE_SYNC", TRACE_SYNC},
{"MON_TRACE_SYNC_DETAIL", TRACE_SYNC_DETAIL},
{"MON_TRACE_NOTICE", TRACE_NOTICE},
{"MON_TRACE_NOTICE_DETAIL", TRACE_NOTICE_DETAIL},
{"MON_TRACE_MLIO", TRACE_MLIO},
{"MON_TRACE_MLIO_DETAIL", TRACE_MLIO_DETAIL},
{"MON_TRACE_TMSYNC", TRACE_TMSYNC},
{"MON_TRACE_INIT", TRACE_INIT},
{"MON_TRACE_RECOVERY", TRACE_RECOVERY},
{"MON_TRACE_STATS", TRACE_STATS},
{"MON_TRACE_EVLOG_MSG", TRACE_EVLOG_MSG},
{"MON_TRACE_ENTRY_EXIT", TRACE_ENTRY_EXIT},
{"MON_TRACE_REDIRECTION", TRACE_REDIRECTION},
{"MON_TRACE_HEALTH", TRACE_HEALTH},
{"MON_TRACE_SIG_HANDLER", TRACE_SIG_HANDLER}
};
// Global trace flags
long trace_settings = 0;
CMonTrace *MonTrace = new CMonTrace ();
CMonTrace::CMonTrace() : tracingEnabled(false), trace_settings_saved(0), trace_file_fb(0), trace_file_base(NULL)
{
numTraceAreas = sizeof(traceAreaList)/sizeof(traceArea);
}
const char *CMonTrace::getenv_str(const char *key)
{
const char *value;
value = getenv(key);
return value;
}
void CMonTrace::getenv_int(const char *key, int &val)
{
const char *p = getenv_str(key);
if (p != NULL)
{
val = atoi(p);
}
}
bool CMonTrace::getenv_bool(const char *key) {
const char *p = getenv_str(key);
bool val = false;
if (p != NULL)
{
val = atoi(p);
}
return val;
}
void CMonTrace::mon_trace_init(const char * traceLevel, const char *pfname)
{
char trace_file_name[MAX_PROCESS_PATH];
// Format default trace file name and remove any existing trace file.
if( getenv("SQ_VIRTUAL_NODES") )
{
sprintf(trace_file_name,"%s/monitor.trace.%d.%s",
getenv("MPI_TMPDIR"),MyPNID,Node_name);
}
else
{
sprintf(trace_file_name,"%s/monitor.trace.%s",
getenv("MPI_TMPDIR"), Node_name);
}
remove(trace_file_name);
if (pfname == NULL)
{ // Caller did not specify a trace file name, get name from
// environment variable if specified.
pfname = getenv_str(str_trace_file);
}
if (pfname != NULL)
{ // User specified trace file name
// Save the base trace file name for possible use later
trace_file_base = new char[strlen(pfname) + 1];
strcpy(trace_file_base, pfname);
if ((strcmp(pfname, "STDOUT") == 0)
|| strcmp(pfname, "STDERR") == 0)
{
strcpy(trace_file_name, pfname);
}
else // Make user specified file name unique per node
{
sprintf(trace_file_name,"%s/%s.%d.%s",getenv("MPI_TMPDIR"),
pfname,MyPNID,Node_name);
}
}
// Get any trace settings that were specified via environment variables
const char *value;
for (int i=0; i<numTraceAreas; i++)
{
value = getenv(traceAreaList[i].id);
if (value != NULL)
{
if (atoi(value) != 0)
// set the enabled flag for this trace area
trace_settings |= traceAreaList[i].bitFlag;
}
}
// Get environment variable specifying whether tracing is enabled
tracingEnabled = getenv_bool(str_trace_enable);
// Get environment variable value for trace buffer size if specified
getenv_int (str_trace_file_fb, trace_file_fb);
// Convert the user specified trace level string to a number. The
// number can be specified as a decimal, octal or hexadecimal
// constant. Combine these flags with current trace_settings that
// may have been set via environment variables.
long trace_flags;
trace_flags = strtol(traceLevel, NULL, 0);
if (errno != ERANGE)
{
trace_settings |= trace_flags;
}
// If any trace settings were specified initialize the trace file
if (trace_settings != 0 || tracingEnabled)
{
tracingEnabled = true;
trace_settings_saved = trace_settings;
trace_init(trace_file_name,
false, // don't append pid to file name
Node_name, // prefix
false);
if (trace_file_fb > 0)
{
trace_set_mem(trace_file_fb);
}
}
}
void CMonTrace::mon_help_bool(const char *key, const char *value,
const char *key_cmp, bool &value_ret)
{
if ((key != NULL) && (strcasecmp(key, key_cmp) == 0))
value_ret = atoi(value);
}
void CMonTrace::mon_help_int(const char *key, const char *value,
const char *key_cmp, int &value_ret) {
if ((key != NULL) && (strcasecmp(key, key_cmp) == 0))
value_ret = atoi(value);
}
const char *CMonTrace::mon_help_str(const char *key, const char *value,
const char *key_cmp)
{
if ((key != NULL) && (strcasecmp(key, key_cmp) == 0))
return value;
return NULL;
}
void CMonTrace::mon_trace_change(const char *key, const char *value)
{
bool trace_was_enabled = tracingEnabled;
const char *pfname;
int old_fb = trace_file_fb;
if (key == NULL)
return;
// Restore saved trace settings in case trace flags get modified
trace_settings = trace_settings_saved;
// Compare the key with each of the trace flag strings. When
// there is an equal compare, assign the value to the appropriate flag.
for (int i=0; i<numTraceAreas; i++)
{
if (strcasecmp(key, traceAreaList[i].id) == 0)
{
if (atoi(value) != 0)
{
// set the enabled flag for this trace area
trace_settings |= traceAreaList[i].bitFlag;
}
else // clear the enabled flag for this trace area
{
trace_settings &= ~traceAreaList[i].bitFlag;
}
break;
}
}
// Save current trace settings
trace_settings_saved = trace_settings;
// Check if tracing is being enabled/disabled
mon_help_bool(key, value, str_trace_enable, tracingEnabled);
// Check if trace file buffer size is being specified
mon_help_int (key, value, str_trace_file_fb, trace_file_fb);
// Check if trace file base name is being specified
pfname = mon_help_str(key, value, str_trace_file);
if (pfname != NULL)
{ // Save trace file base name
delete [] trace_file_base;
trace_file_base = new char[strlen(pfname) + 1];
strcpy(trace_file_base, pfname);
}
if (!trace_was_enabled && tracingEnabled)
{
char fname[MAX_PROCESS_PATH];
// Formulate trace file name
if (trace_file_base != NULL)
{ // User specified trace file name
if ((strcmp(trace_file_base, "STDOUT") == 0)
|| strcmp(trace_file_base, "STDERR") == 0)
{
strcpy(fname, trace_file_base);
}
else
{ // Make user specified file name unique per node
sprintf(fname,"%s/%s.%d.%s",getenv("MPI_TMPDIR"),
trace_file_base,MyPNID,Node_name);
}
}
else
{ // No user specified trace file name, use default
if( getenv("SQ_VIRTUAL_NODES") )
{
sprintf(fname,"%s/monitor.trace.%d.%s",getenv("MPI_TMPDIR"), MyPNID,
Node_name);
}
else
{
sprintf(fname,"%s/monitor.trace.%s",getenv("MPI_TMPDIR"),
Node_name);
}
}
// Tracing was disabled and is now enabled, initialize trace
trace_init(fname,
false, // don't append pid to file name
Node_name, // prefix
false);
}
if (trace_was_enabled && !tracingEnabled)
{
// Tracing was enabled and now is disabled, flush trace. Save
// current trace settings.
trace_flush();
trace_settings = 0;
}
// If a new trace file buffer size was specified, set it
if ((trace_file_fb > 0) && (old_fb != trace_file_fb))
trace_set_mem(trace_file_fb);
}