logging.c 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156
  1. /*
  2. * Copyright 2011-2012 Con Kolivas
  3. *
  4. * This program is free software; you can redistribute it and/or modify it
  5. * under the terms of the GNU General Public License as published by the Free
  6. * Software Foundation; either version 3 of the License, or (at your option)
  7. * any later version. See COPYING for more details.
  8. */
  9. #include "config.h"
  10. #include <unistd.h>
  11. #include "logging.h"
  12. #include "miner.h"
  13. bool opt_debug = false;
  14. bool opt_debug_console = false; // Only used if opt_debug is also enabled
  15. bool opt_log_output = false;
  16. /* per default priorities higher than LOG_NOTICE are logged */
  17. int opt_log_level = LOG_NOTICE;
  18. static void my_log_curses(__maybe_unused int prio, char *f, va_list ap)
  19. {
  20. if (opt_quiet && prio != LOG_ERR)
  21. return;
  22. #ifdef HAVE_CURSES
  23. extern bool use_curses;
  24. if (use_curses && log_curses_only(prio, f, ap))
  25. ;
  26. else
  27. #endif
  28. {
  29. int len = strlen(f);
  30. int cancelstate;
  31. bool scs;
  32. strcpy(f + len - 1, " \n");
  33. scs = !pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cancelstate);
  34. mutex_lock(&console_lock);
  35. vprintf(f, ap);
  36. mutex_unlock(&console_lock);
  37. if (scs)
  38. pthread_setcancelstate(cancelstate, &cancelstate);
  39. }
  40. }
  41. static void log_generic(int prio, const char *fmt, va_list ap);
  42. void vapplog(int prio, const char *fmt, va_list ap)
  43. {
  44. if (!opt_debug && prio == LOG_DEBUG)
  45. return;
  46. log_generic(prio, fmt, ap);
  47. }
  48. void applog(int prio, const char *fmt, ...)
  49. {
  50. va_list ap;
  51. va_start(ap, fmt);
  52. vapplog(prio, fmt, ap);
  53. va_end(ap);
  54. }
  55. /* high-level logging functions, based on global opt_log_level */
  56. /*
  57. * generic log function used by priority specific ones
  58. * equals vapplog() without additional priority checks
  59. */
  60. static void log_generic(int prio, const char *fmt, va_list ap)
  61. {
  62. #ifdef HAVE_SYSLOG_H
  63. if (use_syslog) {
  64. vsyslog(prio, fmt, ap);
  65. }
  66. #else
  67. if (0) {}
  68. #endif
  69. else {
  70. bool writetocon = opt_debug_console || (opt_log_output && prio != LOG_DEBUG) || prio <= LOG_NOTICE;
  71. bool writetofile = !isatty(fileno((FILE *)stderr));
  72. if (!(writetocon || writetofile))
  73. return;
  74. char *f;
  75. int len;
  76. struct timeval tv = {0, 0};
  77. struct tm *tm;
  78. gettimeofday(&tv, NULL);
  79. tm = localtime(&tv.tv_sec);
  80. len = 40 + strlen(fmt) + 22;
  81. f = alloca(len);
  82. sprintf(f, " [%d-%02d-%02d %02d:%02d:%02d] %s\n",
  83. tm->tm_year + 1900,
  84. tm->tm_mon + 1,
  85. tm->tm_mday,
  86. tm->tm_hour,
  87. tm->tm_min,
  88. tm->tm_sec,
  89. fmt);
  90. /* Only output to stderr if it's not going to the screen as well */
  91. if (writetofile) {
  92. va_list apc;
  93. va_copy(apc, ap);
  94. vfprintf(stderr, f, apc); /* atomic write to stderr */
  95. fflush(stderr);
  96. }
  97. if (writetocon)
  98. my_log_curses(prio, f, ap);
  99. }
  100. }
  101. /* we can not generalize variable argument list */
  102. #define LOG_TEMPLATE(PRIO) \
  103. if (PRIO <= opt_log_level) { \
  104. va_list ap; \
  105. va_start(ap, fmt); \
  106. vapplog(PRIO, fmt, ap); \
  107. va_end(ap); \
  108. }
  109. void log_error(const char *fmt, ...)
  110. {
  111. LOG_TEMPLATE(LOG_ERR);
  112. }
  113. void log_warning(const char *fmt, ...)
  114. {
  115. LOG_TEMPLATE(LOG_WARNING);
  116. }
  117. void log_notice(const char *fmt, ...)
  118. {
  119. LOG_TEMPLATE(LOG_NOTICE);
  120. }
  121. void log_info(const char *fmt, ...)
  122. {
  123. LOG_TEMPLATE(LOG_INFO);
  124. }
  125. void log_debug(const char *fmt, ...)
  126. {
  127. LOG_TEMPLATE(LOG_DEBUG);
  128. }