Add handling of a +TIMESTAMP flag in the SAL_LOG environment variable

Change-Id: I9bdcd8b2d7b46a087d7f5461b6f7c3d9f02ec084
This commit is contained in:
Tor Lillqvist
2016-08-18 14:07:00 +03:00
parent f8ba7ff1e5
commit fb00c725bb
2 changed files with 73 additions and 13 deletions

View File

@@ -228,15 +228,21 @@ inline char const * unwrapStream(SAL_UNUSED_PARAMETER StreamIgnore const &) {
with
@verbatim
<switch> ::= <sense><level>("."<area>)?
<switch> ::= <sense><item>
<sense> ::= "+"|"-"
<item> ::= <flag>|<level>("."<area>)?
<flag> ::= "TIMESTAMP"
<level> ::= "INFO"|"WARN"
@endverbatim
If the environment variable is unset, "+WARN" is used instead (which results
in all warnings being output but no infos). If the given value does not
match the regular expression, "+INFO+WARN" is used instead (which in turn
results in everything being output).
If the environment variable is unset, or contains no level, the level
setting "+WARN" is assumed instead (which results in all warnings being
output but no infos). If the given value does not match the regular
expression, "+INFO+WARN" is used instead (which in turn results in
everything being output).
The "+TIMESTAMP" flag causes each output line (as selected by the level
switch(es)) to be prefixed by a timestamp like 2016-08-18:14:04:43.672.
A given macro call's level (INFO or WARN) and area is matched against the
given switches as follows: Only those switches for which the level matches
@@ -251,12 +257,12 @@ inline char const * unwrapStream(SAL_UNUSED_PARAMETER StreamIgnore const &) {
SAL_INFO("other", ...) generate output, while calls like
SAL_INFO("foo", ...) or SAL_INFO("foo.barzzz", ...) do not.
The generated log output consists of the given level ("info" or "warn"), the
given area, the process ID, the thread ID, the source file, and the source
line number, each followed by a colon, followed by a space, the given
message, and a newline. The precise format of the log output is subject to
change. The log output is printed to stderr without further text encoding
conversion.
The generated log output consists of the optinal timestamp, the given level
("info" or "warn"), the given area, the process ID, the thread ID, the
source file, and the source line number, each followed by a colon, followed
by a space, the given message, and a newline. The precise format of the log
output is subject to change. The log output is printed to stderr without
further text encoding conversion.
@see @ref sal_log_areas

View File

@@ -105,6 +105,55 @@ char const * getEnvironmentVariable() {
return env;
}
void maybeOutputTimestamp(std::ostringstream &s) {
char const * env = getEnvironmentVariable();
if (env == nullptr)
return;
for (char const * p = env;;) {
switch (*p++) {
case '\0':
return;
case '+':
{
char const * p1 = p;
while (*p1 != '.' && *p1 != '+' && *p1 != '-' && *p1 != '\0') {
++p1;
}
if (equalStrings(p, p1 - p, RTL_CONSTASCII_STRINGPARAM("TIMESTAMP"))) {
char ts[100];
TimeValue systemTime;
osl_getSystemTime(&systemTime);
TimeValue localTime;
osl_getLocalTimeFromSystemTime(&systemTime, &localTime);
oslDateTime dateTime;
osl_getDateTimeFromTimeValue(&localTime, &dateTime);
struct tm tm;
tm.tm_sec = dateTime.Seconds;
tm.tm_min = dateTime.Minutes;
tm.tm_hour = dateTime.Hours;
tm.tm_mday = dateTime.Day;
tm.tm_mon = dateTime.Month - 1;
tm.tm_year = dateTime.Year - 1900;
strftime(ts, sizeof(ts), "%Y-%m-%d:%H:%M:%S", &tm);
char milliSecs[10];
sprintf(milliSecs, "%03d", dateTime.NanoSeconds/1000000);
s << ts << '.' << milliSecs << ':';
return;
}
char const * p2 = p1;
while (*p2 != '+' && *p2 != '-' && *p2 != '\0') {
++p2;
}
p = p2;
}
break;
default:
; // nothing
}
}
return;
}
#endif
namespace {
@@ -119,7 +168,7 @@ bool report(sal_detail_LogLevel level, char const * area) {
return true;
assert(area != nullptr);
char const * env = getEnvironmentVariable();
if (env == nullptr) {
if (env == nullptr || strcmp(env, "+TIMESTAMP") == 0) {
env = "+WARN";
}
std::size_t areaLen = std::strlen(area);
@@ -156,6 +205,10 @@ bool report(sal_detail_LogLevel level, char const * area) {
} else if (equalStrings(p, p1 - p, RTL_CONSTASCII_STRINGPARAM("WARN")))
{
match = level == SAL_DETAIL_LOG_LEVEL_WARN;
} else if (equalStrings(p, p1 - p, RTL_CONSTASCII_STRINGPARAM("TIMESTAMP")))
{
// handled later
match = false;
} else {
return true;
// upon an illegal SAL_LOG value, everything is considered
@@ -190,8 +243,9 @@ void log(
std::ostringstream s;
#if !defined ANDROID
// On Android, the area will be used as the "tag," and log info already
// contains the PID
// contains timestamp and PID.
if (!sal_use_syslog) {
maybeOutputTimestamp(s);
s << toString(level) << ':';
}
if (!isDebug(level)) {