Skip to content

Commit

Permalink
Correctly handle node and global loglevel configs
Browse files Browse the repository at this point in the history
Prefer local node configs for loglevel, heartbeatloglevel, and
heartbeatinterval, and fall back to the global settings only in the case
that there was no local settings. The global configs are accessed
directly, so that changes to the global configs will immediately affect
all nodes.

fixes #41
  • Loading branch information
robgjansen committed Jun 12, 2012
1 parent 469fa9c commit b6b045b
Show file tree
Hide file tree
Showing 6 changed files with 82 additions and 30 deletions.
5 changes: 5 additions & 0 deletions src/configuration/shd-configuration.c
Original file line number Diff line number Diff line change
Expand Up @@ -189,3 +189,8 @@ GLogLevelFlags configuration_getHeartbeatLogLevel(Configuration* config) {
const gchar* l = (const gchar*) config->heartbeatLogLevelInput;
return configuration_getLevel(config, l);
}

SimulationTime configuration_getHearbeatInterval(Configuration* config) {
MAGIC_ASSERT(config);
return config->heartbeatInterval * SIMTIME_ONE_SECOND;
}
7 changes: 7 additions & 0 deletions src/configuration/shd-configuration.h
Original file line number Diff line number Diff line change
Expand Up @@ -293,6 +293,13 @@ GLogLevelFlags configuration_getLogLevel(Configuration* config);
*/
GLogLevelFlags configuration_getHeartbeatLogLevel(Configuration* config);

/**
* Get the configured heartbeat printing interval.
* @param config a #Configuration object created with configuration_new()
* @return the command line heartbeat interval converted to SimulationTime
*/
SimulationTime configuration_getHearbeatInterval(Configuration* config);

/** @} */

#endif /* SHD_CONFIGURATION_H_ */
50 changes: 35 additions & 15 deletions src/engine/shd-logging.c
Original file line number Diff line number Diff line change
Expand Up @@ -66,11 +66,38 @@ static const gchar* _logging_getLogDomainString(const gchar *log_domain) {
return domains;
}

static gboolean _logging_messageIsFiltered(const gchar *msgLogDomain, GLogLevelFlags msgLogLevel) {
Worker* w = worker_getPrivate();

/* check the local node log level first */
gboolean isNodeLevelSet = FALSE;
if(w->cached_node) {
GLogLevelFlags nodeLevel = node_getLogLevel(w->cached_node);
if(nodeLevel) {
isNodeLevelSet = TRUE;
if(msgLogLevel > nodeLevel) {
return TRUE;
}
}
}

/* only check the global config if the node didnt have a local setting */
if(!isNodeLevelSet && w->cached_engine) {
Configuration* c = engine_getConfig(w->cached_engine);
if(c && (msgLogLevel > configuration_getLogLevel(c))) {
return TRUE;
}
}

return FALSE;
}

/* this func is called whenever g_logv is called, not just in our log code */
void logging_handleLog(const gchar *log_domain, GLogLevelFlags log_level, const gchar *message, gpointer user_data) {
GLogLevelFlags* configuredLogLevel = user_data;

/* check again if the message should be filtered */
if(log_level > *configuredLogLevel) {
if(_logging_messageIsFiltered(log_domain, log_level)) {
return;
}

Expand All @@ -88,21 +115,14 @@ void logging_handleLog(const gchar *log_domain, GLogLevelFlags log_level, const
}
}

void logging_logv(const gchar *log_domain, GLogLevelFlags log_level, const gchar* functionName, const gchar *format, va_list vargs) {
void logging_logv(const gchar *msgLogDomain, GLogLevelFlags msgLogLevel,
const gchar* functionName, const gchar *format, va_list vargs) {
/* this is called by worker threads, so we have access to worker */
Worker* w = worker_getPrivate();

/* see if we can avoid some work because the message is filtered anyway */
if(w->cached_node) {
if(log_level > node_getLogLevel(w->cached_node)) {
return;
}
}
if(w->cached_engine) {
Configuration* c = engine_getConfig(w->cached_engine);
if(c && (log_level > configuration_getLogLevel(c))) {
return;
}
if(_logging_messageIsFiltered(msgLogDomain, msgLogLevel)) {
return;
}

/* format the simulation time if we are running an event */
Expand Down Expand Up @@ -143,16 +163,16 @@ void logging_logv(const gchar *log_domain, GLogLevelFlags log_level, const gchar
g_string_printf(newLogFormatBuffer, "[thread-%i] %s [%s-%s] [%s] [%s] %s",
w->thread_id,
clockString,
_logging_getLogDomainString(log_domain),
_logging_getLogLevelString(log_level),
_logging_getLogDomainString(msgLogDomain),
_logging_getLogLevelString(msgLogLevel),
nodeString,
functionString,
format
);

/* get the new format out of our string buffer and log it */
gchar* newLogFormat = g_string_free(newLogFormatBuffer, FALSE);
g_logv(log_domain, log_level, newLogFormat, vargs);
g_logv(msgLogDomain, msgLogLevel, newLogFormat, vargs);

/* cleanup */
g_free(newLogFormat);
Expand Down
6 changes: 3 additions & 3 deletions src/engine/shd-logging.h
Original file line number Diff line number Diff line change
Expand Up @@ -105,16 +105,16 @@ void logging_handleLog(const gchar *log_domain, GLogLevelFlags log_level, const
*
* In most cases, it is more useful to call logging_log().
*
* @param log_domain a string representing a log domain, normally G_LOG_DOMAIN
* @param log_level the level at which to log the message, one of GLogLevelFlags
* @param msgLogDomain a string representing a log domain, normally G_LOG_DOMAIN
* @param msgLogLevel the level at which to log the message, one of GLogLevelFlags
* @param functionName the name of the calling function, usually __FUNCTION__
* can be used in the calling progress
* @param format a printf() style format string for logging
* @param vargs a variable argument list corresponding to the format string
*
* @see logging_log()
*/
void logging_logv(const gchar *log_domain, GLogLevelFlags log_level, const gchar* functionName, const gchar *format, va_list vargs);
void logging_logv(const gchar *msgLogDomain, GLogLevelFlags msgLogLevel, const gchar* functionName, const gchar *format, va_list vargs);

/**
* High level logging function for logging messages from within a node context.
Expand Down
28 changes: 24 additions & 4 deletions src/node/shd-tracker.c
Original file line number Diff line number Diff line change
Expand Up @@ -98,14 +98,34 @@ void tracker_removeAllocatedBytes(Tracker* tracker, gpointer location) {
void tracker_heartbeat(Tracker* tracker) {
MAGIC_ASSERT(tracker);

guint seconds = (guint) (tracker->interval / SIMTIME_ONE_SECOND);
/* prefer our level over the global config */
GLogLevelFlags level = tracker->loglevel;
if(!level) {
Worker* w = worker_getPrivate();
if(w->cached_engine) {
Configuration* c = engine_getConfig(w->cached_engine);
level = configuration_getHeartbeatLogLevel(c);
}
}

/* prefer our interval over the global config */
SimulationTime interval = tracker->interval;
if(!interval) {
Worker* w = worker_getPrivate();
if(w->cached_engine) {
Configuration* c = engine_getConfig(w->cached_engine);
interval = configuration_getHearbeatInterval(c);
}
}

guint seconds = (guint) (interval / SIMTIME_ONE_SECOND);
double in = (double)(((double)tracker->inputBytesLastInterval) / seconds);
double out = (double)(((double)tracker->outputBytesLastInterval) / seconds);
double cpuutil = (double)(((double)tracker->processingTimeLastInterval) / tracker->interval);
double cpuutil = (double)(((double)tracker->processingTimeLastInterval) / interval);
double mem = (double)(((double)tracker->allocatedBytesTotal) / 1024.0);

/* log the things we are tracking */
logging_log(G_LOG_DOMAIN, tracker->loglevel, __FUNCTION__, "heartbeat: "
logging_log(G_LOG_DOMAIN, level, __FUNCTION__, "heartbeat: "
"Rx %f B/s, Tx %f B/s, CPU %f \%, MEM %f KiB", in, out, cpuutil, mem);

/* clear interval stats */
Expand All @@ -116,5 +136,5 @@ void tracker_heartbeat(Tracker* tracker) {
/* schedule the next heartbeat */
tracker->lastHeartbeat = worker_getPrivate()->clock_now;
HeartbeatEvent* heartbeat = heartbeat_new(tracker);
worker_scheduleEvent((Event*)heartbeat, tracker->interval, 0);
worker_scheduleEvent((Event*)heartbeat, interval, 0);
}
16 changes: 8 additions & 8 deletions src/runnable/action/shd-create-node.c
Original file line number Diff line number Diff line change
Expand Up @@ -111,22 +111,22 @@ void createnodes_run(CreateNodesAction* action) {

Configuration* config = engine_getConfig(worker->cached_engine);

/* prefer node-specific settings, default back to system-wide config */
SimulationTime heartbeatInterval = action->heartbeatIntervalSeconds * SIMTIME_ONE_SECOND;
if(!heartbeatInterval) {
heartbeatInterval = config->heartbeatInterval * SIMTIME_ONE_SECOND;
/* set node-specific settings if we have them.
* the node-specific settings should be 0 if its not set so we know to check
* the global settings later. we avoid using globals here to avoid
* updating all the nodes if the globals changes during execution.
*/
SimulationTime heartbeatInterval = 0;
if(action->heartbeatIntervalSeconds) {
heartbeatInterval = action->heartbeatIntervalSeconds * SIMTIME_ONE_SECOND;
}
GLogLevelFlags heartbeatLogLevel = 0;
if(action->heartbeatLogLevelString) {
heartbeatLogLevel = configuration_getLevel(config, action->heartbeatLogLevelString->str);
} else {
heartbeatLogLevel = configuration_getHeartbeatLogLevel(config);
}
GLogLevelFlags logLevel = 0;
if(action->logLevelString) {
logLevel = configuration_getLevel(config, action->logLevelString->str);
} else {
logLevel = configuration_getLogLevel(config);
}

guint8 logPcap = 0;
Expand Down

0 comments on commit b6b045b

Please sign in to comment.