log.cc 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326
  1. /* Gearman server and library
  2. * Copyright (C) 2008-2009 Brian Aker, Eric Day
  3. * All rights reserved.
  4. *
  5. * Use and distribution licensed under the BSD license. See
  6. * the COPYING file in the parent directory for full text.
  7. */
  8. /**
  9. * @file
  10. * @brief Gearman State Definitions
  11. */
  12. #include <config.h>
  13. #include <libgearman-server/common.h>
  14. #include <algorithm>
  15. #include <cerrno>
  16. #include <cstring>
  17. static pthread_key_t logging_key;
  18. static pthread_once_t intitialize_log_once= PTHREAD_ONCE_INIT;
  19. static void delete_log(void *ptr)
  20. {
  21. if (ptr)
  22. {
  23. free(ptr);
  24. }
  25. }
  26. static void create_log(void)
  27. {
  28. (void) pthread_key_create(&logging_key, delete_log);
  29. }
  30. void gearmand_initialize_thread_logging(const char *identity)
  31. {
  32. (void) pthread_once(&intitialize_log_once, create_log);
  33. void *ptr;
  34. if ((ptr= pthread_getspecific(logging_key)) == NULL)
  35. {
  36. const char *key_to_use= strdup(identity);
  37. (void) pthread_setspecific(logging_key, key_to_use);
  38. }
  39. }
  40. #ifndef __INTEL_COMPILER
  41. #pragma GCC diagnostic ignored "-Wold-style-cast"
  42. #endif
  43. /**
  44. * Log a message.
  45. *
  46. * @param[in] gearman Structure previously initialized with gearman_create() or
  47. * gearman_clone().
  48. * @param[in] verbose Logging level of the message.
  49. * @param[in] format Format and variable argument list of message.
  50. * @param[in] args Variable argument list that has been initialized.
  51. */
  52. static void gearmand_log(const char *position, const char *func /* func */,
  53. gearmand_verbose_t verbose,
  54. const gearmand_error_t error_arg,
  55. const char *format, va_list args)
  56. {
  57. if (Gearmand() == NULL)
  58. {
  59. fprintf(stderr, "%s %7s: ", position, gearmand_verbose_name(verbose));
  60. vprintf(format, args);
  61. fprintf(stderr, "\n");
  62. return;
  63. }
  64. (void) pthread_once(&intitialize_log_once, create_log);
  65. const char *identity= (const char *)pthread_getspecific(logging_key);
  66. if (identity == NULL)
  67. {
  68. identity= "[ main ]";
  69. }
  70. if (Gearmand() && Gearmand()->log_fn)
  71. {
  72. char log_buffer[GEARMAN_MAX_ERROR_SIZE*2];
  73. char *log_buffer_ptr= log_buffer;
  74. size_t remaining_size= sizeof(log_buffer);
  75. {
  76. int length= snprintf(log_buffer_ptr, sizeof(log_buffer), "%s ", identity);
  77. // We just return whatever we have if this occurs
  78. if (length < -1 || (size_t)length >= sizeof(log_buffer))
  79. {
  80. remaining_size= 0;
  81. }
  82. else
  83. {
  84. remaining_size-= size_t(length);
  85. log_buffer_ptr+= length;
  86. }
  87. }
  88. if (remaining_size)
  89. {
  90. int length= vsnprintf(log_buffer_ptr, remaining_size, format, args);
  91. if (length < -1 or size_t(length) >= remaining_size)
  92. {
  93. remaining_size= 0;
  94. }
  95. else
  96. {
  97. remaining_size-= size_t(length);
  98. log_buffer_ptr+= length;
  99. }
  100. }
  101. if (remaining_size and error_arg != GEARMAN_SUCCESS)
  102. {
  103. int length= snprintf(log_buffer_ptr, remaining_size, " %s(%s)", func, gearmand_strerror(error_arg));
  104. if (length < -1 or size_t(length) >= remaining_size)
  105. { }
  106. else
  107. {
  108. remaining_size-= size_t(length);
  109. log_buffer_ptr+= length;
  110. }
  111. }
  112. if (remaining_size and position and verbose != GEARMAND_VERBOSE_INFO)
  113. {
  114. snprintf(log_buffer_ptr, remaining_size, " -> %s", position);
  115. }
  116. // Make sure this is null terminated
  117. log_buffer[sizeof(log_buffer)]= 0;
  118. Gearmand()->log_fn(log_buffer, verbose, (void *)Gearmand()->log_context);
  119. }
  120. else
  121. {
  122. fprintf(stderr, "%s %7s: ", identity, gearmand_verbose_name(verbose));
  123. vprintf(format, args);
  124. fprintf(stderr, "\n");
  125. }
  126. }
  127. void gearmand_log_fatal(const char *position, const char *func, const char *format, ...)
  128. {
  129. va_list args;
  130. if (not Gearmand() || Gearmand()->verbose >= GEARMAND_VERBOSE_FATAL)
  131. {
  132. va_start(args, format);
  133. gearmand_log(position, func, GEARMAND_VERBOSE_FATAL, GEARMAN_SUCCESS, format, args);
  134. va_end(args);
  135. }
  136. }
  137. void gearmand_log_fatal_perror(const char *position, const char *function, const char *message)
  138. {
  139. if (not Gearmand() || Gearmand()->verbose >= GEARMAND_VERBOSE_FATAL)
  140. {
  141. const char *errmsg_ptr;
  142. char errmsg[GEARMAN_MAX_ERROR_SIZE];
  143. errmsg[0]= 0;
  144. #ifdef STRERROR_R_CHAR_P
  145. errmsg_ptr= strerror_r(errno, errmsg, sizeof(errmsg));
  146. #else
  147. strerror_r(errno, errmsg, sizeof(errmsg));
  148. errmsg_ptr= errmsg;
  149. #endif
  150. gearmand_log_fatal(position, function, "%s(%s)", message, errmsg_ptr);
  151. }
  152. }
  153. gearmand_error_t gearmand_log_error(const char *position, const char *function, const char *format, ...)
  154. {
  155. va_list args;
  156. if (not Gearmand() or Gearmand()->verbose >= GEARMAND_VERBOSE_ERROR)
  157. {
  158. va_start(args, format);
  159. gearmand_log(position, function, GEARMAND_VERBOSE_ERROR, GEARMAN_SUCCESS, format, args);
  160. va_end(args);
  161. }
  162. return GEARMAN_UNKNOWN_OPTION;
  163. }
  164. void gearmand_log_warning(const char *position, const char *function, const char *format, ...)
  165. {
  166. va_list args;
  167. if (not Gearmand() || Gearmand()->verbose >= GEARMAND_VERBOSE_WARN)
  168. {
  169. va_start(args, format);
  170. gearmand_log(position, function, GEARMAND_VERBOSE_WARN, GEARMAN_SUCCESS, format, args);
  171. va_end(args);
  172. }
  173. }
  174. // LOG_NOTICE is only used for reporting job status.
  175. void gearmand_log_notice(const char *position, const char *function, const char *format, ...)
  176. {
  177. va_list args;
  178. if (not Gearmand() || Gearmand()->verbose >= GEARMAND_VERBOSE_NOTICE)
  179. {
  180. va_start(args, format);
  181. gearmand_log(position, function, GEARMAND_VERBOSE_NOTICE, GEARMAN_SUCCESS, format, args);
  182. va_end(args);
  183. }
  184. }
  185. void gearmand_log_info(const char *position, const char *function, const char *format, ...)
  186. {
  187. va_list args;
  188. if (not Gearmand() || Gearmand()->verbose >= GEARMAND_VERBOSE_INFO)
  189. {
  190. va_start(args, format);
  191. gearmand_log(position, function, GEARMAND_VERBOSE_INFO, GEARMAN_SUCCESS, format, args);
  192. va_end(args);
  193. }
  194. }
  195. void gearmand_log_debug(const char *position, const char *function, const char *format, ...)
  196. {
  197. va_list args;
  198. if (not Gearmand() || Gearmand()->verbose >= GEARMAND_VERBOSE_DEBUG)
  199. {
  200. va_start(args, format);
  201. gearmand_log(position, function, GEARMAND_VERBOSE_DEBUG, GEARMAN_SUCCESS, format, args);
  202. va_end(args);
  203. }
  204. }
  205. gearmand_error_t gearmand_log_perror(const char *position, const char *function, const char *message)
  206. {
  207. if (not Gearmand() or (Gearmand()->verbose >= GEARMAND_VERBOSE_ERROR))
  208. {
  209. const char *errmsg_ptr;
  210. char errmsg[GEARMAN_MAX_ERROR_SIZE];
  211. errmsg[0]= 0;
  212. #ifdef STRERROR_R_CHAR_P
  213. errmsg_ptr= strerror_r(errno, errmsg, sizeof(errmsg));
  214. #else
  215. strerror_r(errno, errmsg, sizeof(errmsg));
  216. errmsg_ptr= errmsg;
  217. #endif
  218. gearmand_log_error(position, function, "%s(%s)", message, errmsg_ptr);
  219. }
  220. return GEARMAN_ERRNO;
  221. }
  222. gearmand_error_t gearmand_log_gerror(const char *position, const char *function, const gearmand_error_t rc, const char *format, ...)
  223. {
  224. if (gearmand_failed(rc) and rc != GEARMAN_IO_WAIT)
  225. {
  226. va_list args;
  227. if (Gearmand() == NULL or Gearmand()->verbose >= GEARMAND_VERBOSE_ERROR)
  228. {
  229. va_start(args, format);
  230. gearmand_log(position, function, GEARMAND_VERBOSE_ERROR, rc, format, args);
  231. va_end(args);
  232. }
  233. }
  234. else if (rc == GEARMAN_IO_WAIT)
  235. { }
  236. return rc;
  237. }
  238. gearmand_error_t gearmand_log_gerror_warn(const char *position, const char *function, const gearmand_error_t rc, const char *format, ...)
  239. {
  240. if (gearmand_failed(rc) and rc != GEARMAN_IO_WAIT)
  241. {
  242. va_list args;
  243. if (Gearmand() == NULL or Gearmand()->verbose >= GEARMAND_VERBOSE_WARN)
  244. {
  245. va_start(args, format);
  246. gearmand_log(position, function, GEARMAND_VERBOSE_WARN, rc, format, args);
  247. va_end(args);
  248. }
  249. }
  250. else if (rc == GEARMAN_IO_WAIT)
  251. { }
  252. return rc;
  253. }
  254. gearmand_error_t gearmand_log_gai_error(const char *position, const char *function, const int rc, const char *message)
  255. {
  256. if (rc == EAI_SYSTEM)
  257. {
  258. return gearmand_log_perror(position, function, message);
  259. }
  260. gearmand_log_error(position, function, "%s getaddrinfo(%s)", message, gai_strerror(rc));
  261. return GEARMAN_GETADDRINFO;
  262. }
  263. gearmand_error_t gearmand_log_memory_error(const char *position, const char *function, const char *allocator, const char *object_type, size_t count, size_t size)
  264. {
  265. if (count > 1)
  266. {
  267. gearmand_log_error(position, function, "%s(%s, count: %lu size: %lu)", allocator, object_type, static_cast<unsigned long>(count), static_cast<unsigned long>(size));
  268. }
  269. else
  270. {
  271. gearmand_log_error(position, function, "%s(%s, size: %lu)", allocator, object_type, static_cast<unsigned long>(count), static_cast<unsigned long>(size));
  272. }
  273. return GEARMAN_MEMORY_ALLOCATION_FAILURE;
  274. }