mdbx-test: явная установка append-режима для stdout/stderr.

This commit is contained in:
Леонид Юрьев (Leonid Yuriev) 2023-11-10 21:14:32 +03:00
parent d9f49b17de
commit cfce4ef4d3
3 changed files with 57 additions and 58 deletions

View File

@ -56,7 +56,7 @@ namespace logging {
static std::string prefix; static std::string prefix;
static std::string suffix; static std::string suffix;
static loglevel level; static loglevel level;
static FILE *last; static FILE *flow;
void setlevel(loglevel priority) { void setlevel(loglevel priority) {
level = priority; level = priority;
@ -67,13 +67,13 @@ void setlevel(loglevel priority) {
log_trace("set mdbx debug-opts: 0x%02x", rc); log_trace("set mdbx debug-opts: 0x%02x", rc);
} }
void setup(const std::string &_prefix) { prefix = _prefix; }
void setup(loglevel priority, const std::string &_prefix) { void setup(loglevel priority, const std::string &_prefix) {
setlevel(priority); setlevel(priority);
prefix = _prefix; setup(_prefix);
} }
void setup(const std::string &_prefix) { prefix = _prefix; }
const char *level2str(const loglevel alevel) { const char *level2str(const loglevel alevel) {
switch (alevel) { switch (alevel) {
default: default:
@ -108,18 +108,13 @@ bool output(const loglevel priority, const char *format, ...) {
return true; return true;
} }
bool ln() { void ln() {
if (last) { if (flow) {
putc('\n', last); putc('\n', flow);
fflush(last); if (flow != stdout)
if (last == stderr) {
putc('\n', stdout); putc('\n', stdout);
fflush(stdout); flow = nullptr;
}
last = nullptr;
return true;
} }
return false;
} }
void output_nocheckloglevel_ap(const logging::loglevel priority, void output_nocheckloglevel_ap(const logging::loglevel priority,
@ -139,8 +134,7 @@ void output_nocheckloglevel_ap(const logging::loglevel priority,
if (rc != MDBX_SUCCESS) if (rc != MDBX_SUCCESS)
failure_perror("localtime_r()", rc); failure_perror("localtime_r()", rc);
last = stdout; fprintf(stdout,
fprintf(last,
"[ %02d%02d%02d-%02d:%02d:%02d.%06d_%05lu %-10s %.4s ] %s" /* TODO */, "[ %02d%02d%02d-%02d:%02d:%02d.%06d_%05lu %-10s %.4s ] %s" /* TODO */,
tm.tm_year - 100, tm.tm_mon + 1, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_year - 100, tm.tm_mon + 1, tm.tm_mday, tm.tm_hour, tm.tm_min,
tm.tm_sec, chrono::fractional2us(now.fractional), (long)osal_getpid(), tm.tm_sec, chrono::fractional2us(now.fractional), (long)osal_getpid(),
@ -150,19 +144,17 @@ void output_nocheckloglevel_ap(const logging::loglevel priority,
memset(&ones, 0, sizeof(ones)) /* zap MSVC and other goofy compilers */; memset(&ones, 0, sizeof(ones)) /* zap MSVC and other goofy compilers */;
if (same_or_higher(priority, error)) if (same_or_higher(priority, error))
va_copy(ones, ap); va_copy(ones, ap);
vfprintf(last, format, ap); vfprintf(stdout, format, ap);
size_t len = strlen(format); size_t len = strlen(format);
char end = len ? format[len - 1] : '\0'; char end = len ? format[len - 1] : '\0';
switch (end) { switch (end) {
default: default:
putc('\n', last); putc('\n', stdout);
MDBX_CXX17_FALLTHROUGH; // fall through break;
case '\n': case '\n':
fflush(last); break;
last = nullptr;
MDBX_CXX17_FALLTHROUGH; // fall through
case ' ': case ' ':
case '_': case '_':
case ':': case ':':
@ -172,46 +164,39 @@ void output_nocheckloglevel_ap(const logging::loglevel priority,
case '\b': case '\b':
case '\r': case '\r':
case '\0': case '\0':
flow = stdout;
break; break;
} }
if (same_or_higher(priority, error)) { if (same_or_higher(priority, error)) {
if (last != stderr) { if (flow)
fprintf(stderr, "[ %05lu %-10s %.4s ] %s", (long)osal_getpid(), flow = stderr;
prefix.c_str(), level2str(priority), suffix.c_str()); fprintf(stderr, "[ %05lu %-10s %.4s ] %s", (long)osal_getpid(),
vfprintf(stderr, format, ones); prefix.c_str(), level2str(priority), suffix.c_str());
if (end == '\n') vfprintf(stderr, format, ones);
fflush(stderr);
else
last = stderr;
}
va_end(ones); va_end(ones);
} }
} }
bool feed_ap(const char *format, va_list ap) { bool feed_ap(const char *format, va_list ap) {
if (!last) if (!flow)
return false; return false;
if (last == stderr) { if (flow == stderr) {
va_list ones; va_list ones;
va_copy(ones, ap); va_copy(ones, ap);
vfprintf(stdout, format, ones); vfprintf(stdout, format, ones);
va_end(ones); va_end(ones);
} }
vfprintf(last, format, ap); vfprintf(flow, format, ap);
size_t len = strlen(format); size_t len = strlen(format);
if (len && format[len - 1] == '\n') { if (len && format[len - 1] == '\n')
fflush(last); flow = nullptr;
if (last == stderr)
fflush(stdout);
last = nullptr;
}
return true; return true;
} }
bool feed(const char *format, ...) { bool feed(const char *format, ...) {
if (!last) if (!flow)
return false; return false;
va_list ap; va_list ap;
@ -299,73 +284,73 @@ void progress_canary(bool active) {
} // namespace logging } // namespace logging
void log_extra(const char *msg, ...) { void log_extra(const char *msg, ...) {
logging::ln();
if (logging::same_or_higher(logging::extra, logging::level)) { if (logging::same_or_higher(logging::extra, logging::level)) {
va_list ap; va_list ap;
va_start(ap, msg); va_start(ap, msg);
logging::output_nocheckloglevel_ap(logging::extra, msg, ap); logging::output_nocheckloglevel_ap(logging::extra, msg, ap);
va_end(ap); va_end(ap);
} else }
logging::last = nullptr;
} }
void log_trace(const char *msg, ...) { void log_trace(const char *msg, ...) {
logging::ln();
if (logging::same_or_higher(logging::trace, logging::level)) { if (logging::same_or_higher(logging::trace, logging::level)) {
va_list ap; va_list ap;
va_start(ap, msg); va_start(ap, msg);
logging::output_nocheckloglevel_ap(logging::trace, msg, ap); logging::output_nocheckloglevel_ap(logging::trace, msg, ap);
va_end(ap); va_end(ap);
} else }
logging::last = nullptr;
} }
void log_debug(const char *msg, ...) { void log_debug(const char *msg, ...) {
logging::ln();
if (logging::same_or_higher(logging::debug, logging::level)) { if (logging::same_or_higher(logging::debug, logging::level)) {
va_list ap; va_list ap;
va_start(ap, msg); va_start(ap, msg);
logging::output_nocheckloglevel_ap(logging::debug, msg, ap); logging::output_nocheckloglevel_ap(logging::debug, msg, ap);
va_end(ap); va_end(ap);
} else }
logging::last = nullptr;
} }
void log_verbose(const char *msg, ...) { void log_verbose(const char *msg, ...) {
logging::ln();
if (logging::same_or_higher(logging::verbose, logging::level)) { if (logging::same_or_higher(logging::verbose, logging::level)) {
va_list ap; va_list ap;
va_start(ap, msg); va_start(ap, msg);
logging::output_nocheckloglevel_ap(logging::verbose, msg, ap); logging::output_nocheckloglevel_ap(logging::verbose, msg, ap);
va_end(ap); va_end(ap);
} else }
logging::last = nullptr;
} }
void log_notice(const char *msg, ...) { void log_notice(const char *msg, ...) {
logging::ln();
if (logging::same_or_higher(logging::notice, logging::level)) { if (logging::same_or_higher(logging::notice, logging::level)) {
va_list ap; va_list ap;
va_start(ap, msg); va_start(ap, msg);
logging::output_nocheckloglevel_ap(logging::notice, msg, ap); logging::output_nocheckloglevel_ap(logging::notice, msg, ap);
va_end(ap); va_end(ap);
} else }
logging::last = nullptr;
} }
void log_warning(const char *msg, ...) { void log_warning(const char *msg, ...) {
logging::ln();
if (logging::same_or_higher(logging::warning, logging::level)) { if (logging::same_or_higher(logging::warning, logging::level)) {
va_list ap; va_list ap;
va_start(ap, msg); va_start(ap, msg);
logging::output_nocheckloglevel_ap(logging::warning, msg, ap); logging::output_nocheckloglevel_ap(logging::warning, msg, ap);
va_end(ap); va_end(ap);
} else }
logging::last = nullptr;
} }
void log_error(const char *msg, ...) { void log_error(const char *msg, ...) {
logging::ln();
if (logging::same_or_higher(logging::error, logging::level)) { if (logging::same_or_higher(logging::error, logging::level)) {
va_list ap; va_list ap;
va_start(ap, msg); va_start(ap, msg);
logging::output_nocheckloglevel_ap(logging::error, msg, ap); logging::output_nocheckloglevel_ap(logging::error, msg, ap);
va_end(ap); va_end(ap);
} else }
logging::last = nullptr;
} }
void log_trouble(const char *where, const char *what, int errnum) { void log_trouble(const char *where, const char *what, int errnum) {
@ -376,4 +361,7 @@ bool log_enabled(const logging::loglevel priority) {
return logging::same_or_higher(priority, logging::level); return logging::same_or_higher(priority, logging::level);
} }
void log_flush(void) { fflushall(); } void log_flush(void) {
logging::ln();
fflushall();
}

View File

@ -55,7 +55,7 @@ bool MDBX_PRINTF_ARGS(2, 3)
output(const loglevel priority, const char *format, ...); output(const loglevel priority, const char *format, ...);
bool feed_ap(const char *format, va_list ap); bool feed_ap(const char *format, va_list ap);
bool MDBX_PRINTF_ARGS(1, 2) feed(const char *format, ...); bool MDBX_PRINTF_ARGS(1, 2) feed(const char *format, ...);
bool ln(); void ln();
void inline MDBX_PRINTF_ARGS(2, 3) void inline MDBX_PRINTF_ARGS(2, 3)
output_nocheckloglevel(const loglevel priority, const char *format, ...) { output_nocheckloglevel(const loglevel priority, const char *format, ...) {

View File

@ -267,8 +267,19 @@ static void fixup4qemu(actor_params &params) {
(void)params; (void)params;
} }
int main(int argc, char *const argv[]) { static void set_linebuf_append(FILE *out) {
setvbuf(out, NULL, _IOLBF, 65536);
#if !defined(_WIN32) && !defined(_WIN64)
int fd = fileno(out);
int flags = fcntl(fd, F_GETFD);
if (flags != -1)
(void)fcntl(fd, F_SETFD, O_APPEND | flags);
#endif /* !Windows */
}
int main(int argc, char *const argv[]) {
set_linebuf_append(stdout);
set_linebuf_append(stderr);
#ifdef _DEBUG #ifdef _DEBUG
log_trace("#argc = %d", argc); log_trace("#argc = %d", argc);
for (int i = 0; i < argc; ++i) for (int i = 0; i < argc; ++i)