// EterBase/Debug.cpp (the 40250 non-_DEBUG build): OpenLogFile sends stderr to syserr.txt and, with true, // opens log.txt for Log*/Trace*; SetLogLevel filters Log*. Its own process because stderr is redirected, so // failures go to stdout. #include "EterBase/StdAfx.h" #include "EterBase/Debug.h" #include #include #include #include #include static int g_failures = 0; #define CHECK(cond) \ do { \ if (!(cond)) { \ std::printf("%s:%d: CHECK(%s)\n", __FILE__, __LINE__, #cond); \ ++g_failures; \ } \ } while (0) static std::string ReadAll(const char* path) { std::ifstream in(path); std::stringstream ss; ss << in.rdbuf(); return ss.str(); } int main() { char dir[] = "/tmp/mt_debuglog_XXXXXX"; if (!mkdtemp(dir) || chdir(dir) != 0) return 1; // Before OpenLogFile nothing reaches a log file. Tracenf("before %d", 1); OpenLogFile(true); SetLogLevel(1); Logn(0, "level0"); Logn(1, "level1"); Lognf(2, "lognf %d", 2); Logf(0, "logf-filtered"); Tracen("tracen"); Tracef("tracef %s\n", "x"); TraceError("oops %d", 7); LogFilef("filef %d\n", 3); fflush(stderr); const std::string log = ReadAll("log.txt"); const std::string syserr = ReadAll("syserr.txt"); CHECK(log.find("before") == std::string::npos); CHECK(log.find("level0") == std::string::npos); CHECK(log.find(" :: level1") != std::string::npos); CHECK(log.find(" :: lognf 2\n") != std::string::npos); CHECK(log.find("logf-filtered") == std::string::npos); CHECK(log.find(" :: tracen") != std::string::npos); CHECK(log.find(" :: tracef x\n") != std::string::npos); CHECK(log.find(" :: SYSERR: oops 7\n") != std::string::npos); CHECK(log.find(" :: filef 3\n") != std::string::npos); CHECK(syserr.find(" :: oops 7\n") != std::string::npos && syserr.find("SYSERR") == std::string::npos); unlink("log.txt"); unlink("syserr.txt"); chdir("/"); rmdir(dir); if (g_failures) std::printf("port_debug_log_test: %d failure(s)\n", g_failures); else std::puts("port_debug_log_test: ok"); return g_failures ? 1 : 0; }