init.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489
  1. /*
  2. * init.c
  3. * Copyright 2001-2003, Meiosys (www.meiosys.com). All rights reserved.
  4. * See the COPYING file for the terms of usage and distribution.
  5. */
  6. #ifdef HAVE_CONFIG_H
  7. #endif
  8. #include <tchar.h>
  9. #include <stdlib.h>
  10. #include "log4c/config.h"
  11. #include "log4c/init.h"
  12. #include "log4c/category.h"
  13. #include "log4c/appender.h"
  14. #include "log4c/layout.h"
  15. #include "log4c/rollingpolicy.h"
  16. #include "log4c/rc.h"
  17. #include "sd/error.h"
  18. #include "sd/sprintf.h"
  19. #include "sd/factory.h"
  20. #include "sd/sd_xplatform.h"
  21. #include "log4c/appender_type_stream.h"
  22. #include "log4c/appender_type_stream2.h"
  23. #include "log4c/appender_type_syslog.h"
  24. #include "log4c/appender_type_mmap.h"
  25. #include "log4c/appender_type_rollingfile.h"
  26. #include "log4c/rollingpolicy_type_sizewin.h"
  27. #include "log4c/layout_type_basic.h"
  28. #include "log4c/layout_type_dated.h"
  29. #include "log4c/layout_type_basic_r.h"
  30. #include "log4c/layout_type_dated_r.h"
  31. static const TCHAR version[] = _T("$Id$");
  32. #if defined(__LOG4C_DEBUG__) && defined(__GLIBC__)
  33. #include <mcheck.h>
  34. #endif
  35. // 布局类型数组;
  36. static const log4c_layout_type_t * const layout_types[] = {
  37. &log4c_layout_type_basic,
  38. &log4c_layout_type_dated,
  39. /* These appenders are not yet ported with msvc */
  40. #ifndef _WIN32
  41. &log4c_layout_type_basic_r,
  42. &log4c_layout_type_dated_r
  43. #endif
  44. };
  45. // 布局数组大小;
  46. static size_t nlayout_types = sizeof(layout_types) / sizeof(layout_types[0]);
  47. // 日志目的地数组;
  48. static const log4c_appender_type_t * const appender_types[] = {
  49. &log4c_appender_type_stream,
  50. &log4c_appender_type_stream2,
  51. #ifdef HAVE_MMAP
  52. &log4c_appender_type_mmap,
  53. #endif
  54. #ifdef HAVE_SYSLOG_H
  55. &log4c_appender_type_syslog,
  56. #endif
  57. #ifdef WITH_ROLLINGFILE
  58. &log4c_appender_type_rollingfile
  59. #endif
  60. };
  61. // 目的地数组大小;
  62. static size_t nappender_types = sizeof(appender_types) / sizeof(appender_types[0]);
  63. #ifdef WITH_ROLLINGFILE
  64. static const log4c_rollingpolicy_type_t * const rollingpolicy_types[] = {
  65. &log4c_rollingpolicy_type_sizewin
  66. };
  67. static size_t nrollingpolicy_types =
  68. sizeof(rollingpolicy_types) / sizeof(rollingpolicy_types[0]);
  69. #endif
  70. // 静态变量标志log4c是否初始化;
  71. static int log4c_is_init = 0;
  72. // 资源文件结构体;
  73. typedef struct rcfile
  74. {
  75. TCHAR name[256];
  76. time_t ctime;
  77. int exists;
  78. } rcfile_t;
  79. // 资源结构体;
  80. static rcfile_t rcfiles[] = {
  81. {_T("$LOG4C_RCPATH/log4crc.txt") },
  82. {_T("$HOME/.log4crc.txt") },
  83. {_T("./log4crc.txt") }
  84. };
  85. // 资源文件数组大小;
  86. static const int nrcfiles = sizeof(rcfiles) / sizeof(rcfiles[0]);
  87. /******************************************************************************/
  88. extern int log4c_init(void)
  89. {// C语言,需要把所有变量声明在函数开始位置;
  90. size_t i;
  91. int j = 0;
  92. int ret = 0;
  93. const TCHAR* priority = NULL;
  94. const TCHAR* appender = NULL;
  95. sd_debug(_T("log4c_init["));
  96. /* activate GLIBC allocation debugging */
  97. #if defined(__LOG4C_DEBUG__) && defined(__GLIBC__)
  98. mtrace();
  99. #endif
  100. if (log4c_is_init)
  101. {// log4c已初始化;
  102. sd_debug(_T("log4c already initialized ]"));
  103. return 0;
  104. }
  105. // 自增,标志log4c已初始化;
  106. log4c_is_init++;
  107. /* Initialize default types: layouts, appenders, rollingpolicies */
  108. sd_debug(_T("intializing default types: appenders, layouts, rollingpolicies"));
  109. // 初始化静态布局数组;
  110. for (i = 0; i < nlayout_types; i++)
  111. log4c_layout_type_set(layout_types[i]);
  112. // 初始化静态日志目的地数组;
  113. for (i = 0; i < nappender_types; i++)
  114. log4c_appender_type_set(appender_types[i]);
  115. #ifdef WITH_ROLLINGFILE
  116. for (i = 0; i < nrollingpolicy_types; i++)
  117. log4c_rollingpolicy_type_set(rollingpolicy_types[i]);
  118. #endif
  119. /* load configuration files */
  120. sd_debug(_T("looking for conf files..."));
  121. _sntprintf(
  122. rcfiles[0].name,
  123. sizeof(rcfiles[0].name) - 1,
  124. _T("%s/log4crc.txt"),
  125. _tgetenv(_T("LOG4C_RCPATH")) ? _tgetenv(_T("LOG4C_RCPATH")) : LOG4C_RCPATH);
  126. _sntprintf(
  127. rcfiles[1].name, sizeof(rcfiles[1].name) - 1, _T("%s/.log4crc.txt"),
  128. _tgetenv(_T("HOME")) ? _tgetenv(_T("HOME")) : _T(""));
  129. for (j = 0; j < nrcfiles; j++)
  130. {
  131. sd_debug(_T("checking for conf file at '%s'"), rcfiles[j].name);
  132. if (SD_ACCESS_READ(rcfiles[j].name)) //文件是否只读,只读继续;
  133. continue;
  134. if (SD_STAT_CTIME(rcfiles[j].name,&rcfiles[j].ctime) != 0)
  135. sd_error(_T("sd_stat_ctime %s failed"), rcfiles[j].name);
  136. rcfiles[j].exists=1;
  137. if (log4c_load(rcfiles[j].name) == -1)
  138. {
  139. sd_error(_T("loading %s failed"), rcfiles[j].name);
  140. ret = -1;
  141. }
  142. else
  143. sd_debug(_T("loading %s succeeded"), rcfiles[j].name);
  144. }
  145. /* override configuration with environment variables */
  146. sd_debug(_T("checking environment variables..."));
  147. if ( (priority = _tgetenv(_T("LOG4C_PRIORITY"))) != NULL)
  148. {
  149. sd_debug(_T("setting priority of root category to '%s'"), priority);
  150. log4c_category_set_priority(log4c_category_get(_T("root")), log4c_priority_to_int(priority));
  151. }
  152. if ( (appender = _tgetenv(_T("LOG4C_APPENDER"))) != NULL)
  153. {
  154. sd_debug(_T("setting appender of root category to '%s'"),appender);
  155. log4c_category_set_appender(log4c_category_get(_T("root")), log4c_appender_get(appender));
  156. }
  157. /*
  158. * For debug dump current types and instances:
  159. * this allows the caller of log4c_init() to see:
  160. * 1. all types currently registered, including perhaps his own.
  161. * 2. all instances instantiated via the configuration file.
  162. *
  163. * If the caller goes on to programmatically create instaces then he
  164. * can call log4c_dump_all_instances() later himself to
  165. * verify that they were created as expected.
  166. *
  167. */
  168. #ifdef __SD_DEBUG__
  169. if( _tgetenv("SD_DEBUG")){
  170. log4c_dump_all_types(stderr);
  171. log4c_dump_all_instances(stderr);
  172. }
  173. #endif
  174. sd_debug(_T("]"));
  175. return ret;
  176. }
  177. /******************************************************************************/
  178. void __log4c_reread(void)
  179. {
  180. time_t file_ctime;
  181. int i;
  182. for (i = 0; i < nrcfiles; i++){
  183. /* only reread files that existed when we first initialized */
  184. if (rcfiles[i].exists && SD_STAT_CTIME(rcfiles[i].name,&file_ctime) == 0){
  185. /* time_t is number of second since epoch, just compare for == */
  186. if (file_ctime != rcfiles[i].ctime){
  187. sd_debug(_T("Need reread on file %s\n"),rcfiles[i].name);
  188. SD_STAT_CTIME(rcfiles[i].name,&rcfiles[i].ctime);
  189. if (log4c_rc_load(log4c_rc, rcfiles[i].name) == -1){
  190. sd_error(_T("re-loading config file %s failed"), rcfiles[i].name);
  191. }
  192. }
  193. }
  194. }
  195. }
  196. /******************************************************************************/
  197. /*
  198. * Rereads any log4crc files that have changed
  199. */
  200. void log4c_reread(void)
  201. {
  202. #ifdef __ENABLE_REREAD__
  203. if (0 != log4c_rc->config.reread){
  204. __log4c_reread();
  205. }
  206. #endif
  207. }
  208. /******************************************************************************/
  209. extern int log4c_fini(void)
  210. {
  211. int rc = 0;
  212. /* Some acceptable use of goto here to avoid lots of nested ifs
  213. * when we need a quick exit
  214. */
  215. sd_debug(_T("log4c_fini["));
  216. if (log4c_rc->config.nocleanup){
  217. sd_debug(_T("not cleaning up--nocleanup specified in conf"));
  218. rc = -1;
  219. goto log4c_fini_exit;
  220. }
  221. if (!log4c_is_init){
  222. rc = 0;
  223. sd_debug(_T("not cleaning up--log4c not initialized"));
  224. goto log4c_fini_exit;
  225. }
  226. log4c_is_init--;
  227. sd_debug(_T("cleaning up category, appender, layout androllingpolicy instances"));
  228. if (log4c_category_factory) {
  229. sd_factory_delete(log4c_category_factory);
  230. log4c_category_factory = NULL;
  231. }
  232. if (log4c_appender_factory) {
  233. sd_factory_delete(log4c_appender_factory);
  234. log4c_appender_factory = NULL;
  235. }
  236. if (log4c_layout_factory) {
  237. sd_factory_delete(log4c_layout_factory);
  238. log4c_layout_factory = NULL;
  239. }
  240. if (log4c_rollingpolicy_factory) {
  241. sd_factory_delete(log4c_rollingpolicy_factory);
  242. log4c_rollingpolicy_factory = NULL;
  243. }
  244. ///////////////////////////////////////////////////////////////////////////
  245. // 检测出来需要额外释放的内存 [7/23/2010 jesse]
  246. log4c_layout_delete_global();
  247. log4c_appender_delete_global();
  248. log4c_rollingpolicy_delete_global();
  249. #ifdef __SD_DEBUG__
  250. if( _tgetenv("SD_DEBUG")){
  251. sd_debug("Instance dump after cleanup:");
  252. log4c_dump_all_instances(stderr);
  253. }
  254. #endif
  255. #if defined(__LOG4C_DEBUG__) && defined(__GLIBC__)
  256. muntrace();
  257. #endif
  258. log4c_fini_exit:
  259. sd_debug(_T("]"));
  260. return 0;
  261. }
  262. /******************************************************************************/
  263. #ifdef __GNUC__
  264. extern void __attribute__ ((constructor)) __log4c_init(void)
  265. {
  266. #ifdef WITH_CONSTRUCTORS
  267. log4c_init();
  268. #endif
  269. }
  270. extern void __attribute__ ((destructor)) __log4c_fini(void)
  271. {
  272. #ifdef WITH_CONSTRUCTORS
  273. log4c_fini();
  274. #endif
  275. }
  276. #endif
  277. /******************************************************************************/
  278. extern void log4c_dump_all_types(FILE *fp){
  279. /*
  280. *
  281. * For debug, dump all the types that have been registered during init. We just
  282. * display the name of the the type for the moment--the rest of the type info
  283. * right now consists of functions to call, so not really printable.
  284. */
  285. log4c_appender_types_print(fp);
  286. log4c_layout_types_print(fp);
  287. #ifdef WITH_ROLLINGFILE
  288. log4c_rollingpolicy_types_print(fp);
  289. #endif
  290. }
  291. extern void log4c_dump_all_instances(FILE *fp){
  292. /*
  293. * Also dump any instances that were created during init by
  294. * reading the conf file.
  295. *
  296. * An instances of a type consists of the base
  297. * type information (name plus function table) and an instance name and
  298. * configuration. For example one can have an instance of the rollingfile
  299. * appender which logs to /var/tmp and another instance which logs to
  300. * /usr/tmp. They are both of type rollingfile, but are distinct instances of
  301. * it
  302. */
  303. _ftprintf(fp, _T("instance dump follows (may be empty):\n"));
  304. sd_factory_print(log4c_category_factory, fp);
  305. sd_factory_print(log4c_appender_factory, fp);
  306. sd_factory_print(log4c_layout_factory, fp);
  307. #ifdef WITH_ROLLINGFILE
  308. sd_factory_print(log4c_rollingpolicy_factory, fp);
  309. #endif
  310. }
  311. //////////////////////////////////////////////////////////////////////////
  312. ///下面函数为自己写的一些函数,为使用log4c起来方便而设置的
  313. /** 带有配置文件名的初始化函数
  314. 完成功能和log4c_init完全一致,只是这里的配置文件名以参数形式传入的
  315. @returns 0 for success .
  316. 作者:jesse 日期:2008-9-6
  317. */
  318. extern int log4c_init_with_cfg_file(const TCHAR *strCfgFileName)
  319. {
  320. size_t i;
  321. int ret = 0;
  322. sd_debug(_T("log4c_init["));
  323. /* activate GLIBC allocation debugging */
  324. #if defined(__LOG4C_DEBUG__) && defined(__GLIBC__)
  325. mtrace();
  326. #endif
  327. if (log4c_is_init)
  328. {
  329. sd_debug(_T("log4c already initialized ]"));
  330. return 0;
  331. }
  332. log4c_is_init++;
  333. /* Initialize default types: layouts, appenders, rollingpolicies */
  334. sd_debug(_T("intializing default types: appenders, layouts, rollingpolicies"));
  335. for (i = 0; i < nlayout_types; i++)
  336. {
  337. log4c_layout_type_set(layout_types[i]);
  338. }
  339. for (i = 0; i < nappender_types; i++)
  340. {
  341. log4c_appender_type_set(appender_types[i]);
  342. }
  343. #ifdef WITH_ROLLINGFILE
  344. for (i = 0; i < nrollingpolicy_types; i++)
  345. {
  346. log4c_rollingpolicy_type_set(rollingpolicy_types[i]);
  347. }
  348. #endif
  349. /* load configuration files */
  350. //{
  351. ///int i;
  352. sd_debug(_T("looking for conf files..."));
  353. if(NULL == strCfgFileName)
  354. {
  355. sd_debug(_T("log4c_init[ERROR:strCfgFileName==NULL"));
  356. ret = -1;
  357. }
  358. else
  359. {
  360. time_t timeFile;
  361. sd_debug(_T("checking for conf file at '%s'"), strCfgFileName);
  362. if (SD_ACCESS_READ(strCfgFileName))
  363. {
  364. sd_error(_T("loading %s failed"), strCfgFileName);
  365. ret = -1;
  366. }
  367. else
  368. {
  369. if (SD_STAT_CTIME(strCfgFileName, &timeFile) != 0)
  370. {
  371. sd_error(_T("sd_stat_ctime %s failed"), strCfgFileName);
  372. }
  373. ///rcfiles[i].exists=1;
  374. if (log4c_load(strCfgFileName) == -1)
  375. {
  376. sd_error(_T("loading %s failed"), strCfgFileName);
  377. ret = -1;
  378. }
  379. else
  380. {
  381. sd_debug(_T("loading %s succeeded"), strCfgFileName);
  382. }
  383. }
  384. }
  385. //}
  386. /* override configuration with environment variables */
  387. {
  388. const TCHAR* priority;
  389. const TCHAR* appender;
  390. sd_debug(_T("checking environment variables..."));
  391. if ( (priority = _tgetenv(_T("LOG4C_PRIORITY"))) != NULL){
  392. sd_debug(_T("setting priority of root category to '%s'"),priority);
  393. log4c_category_set_priority(log4c_category_get(_T("root")),
  394. log4c_priority_to_int(priority));
  395. }
  396. if ( (appender = _tgetenv(_T("LOG4C_APPENDER"))) != NULL){
  397. sd_debug(_T("setting appender of root category to '%s'"),appender);
  398. log4c_category_set_appender(log4c_category_get(_T("root")), log4c_appender_get(appender));
  399. }
  400. }
  401. /*
  402. * For debug dump current types and instances:
  403. * ptrThis allows the caller of log4c_init() to see:
  404. * 1. all types currently registered, including perhaps his own.
  405. * 2. all instances instantiated via the configuration file.
  406. *
  407. * If the caller goes on to programmatically create instaces then he
  408. * can call log4c_dump_all_instances() later himself to
  409. * verify that they were created as expected.
  410. *
  411. */
  412. #ifdef __SD_DEBUG__
  413. if( _tgetenv("SD_DEBUG")){
  414. log4c_dump_all_types(stderr);
  415. log4c_dump_all_instances(stderr);
  416. }
  417. #endif
  418. sd_debug(_T("]"));
  419. return ret;
  420. }