rc.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386
  1. static const char version[] = "1.2.1";
  2. /*
  3. * rc.c
  4. *
  5. * Copyright 2001-2003, Meiosys (www.meiosys.com). All rights reserved.
  6. *
  7. * See the COPYING file for the terms of usage and distribution.
  8. */
  9. #ifdef HAVE_CONFIG_H
  10. #include "config.h"
  11. #endif
  12. #include <log4c/rc.h>
  13. #include <log4c/category.h>
  14. #include <log4c/appender.h>
  15. #include <log4c/layout.h>
  16. #include <log4c/appender_type_rollingfile.h>
  17. #include <log4c/rollingpolicy.h>
  18. #include <log4c/rollingpolicy_type_sizewin.h>
  19. #include <sd/error.h>
  20. #include <sd/domnode.h>
  21. #include <sd/malloc.h>
  22. #include <sd/sd_xplatform.h>
  23. #include <sd/factory.h>
  24. #include <stdlib.h>
  25. #include <string.h>
  26. static log4c_rc_t __log4c_rc = { { 0, 0, 0, 0 } };
  27. log4c_rc_t* const log4c_rc = &__log4c_rc;
  28. /******************************************************************************/
  29. static long parse_byte_size (const char *astring)
  30. {
  31. /* Parse size in bytes depending on the suffix. Valid suffixes are KB, MB and GB */
  32. size_t sz = strlen (astring);
  33. long res = strtol(astring, (char **) NULL, 10);
  34. if (res <= 0)
  35. return 0;
  36. if (astring[ sz - 1 ] == 'B') {
  37. switch (astring[ sz - 2 ]) {
  38. case 'K':
  39. res *= 1024;
  40. break;
  41. case 'M':
  42. res *= 1024 * 1024;
  43. break;
  44. case 'G':
  45. res *= 1024 * 1024 * 1024;
  46. break;
  47. default:
  48. sd_debug("Wrong suffix parsing size in bytes for string %s, ignoring suffix",
  49. astring);
  50. }
  51. }
  52. sd_debug("Parsed size parameter %s to value %ld",astring, res);
  53. return (res);
  54. }
  55. /******************************************************************************/
  56. static int config_load(log4c_rc_t* this, sd_domnode_t* anode)
  57. {
  58. sd_list_iter_t* i = NULL;
  59. for (i = sd_list_begin(anode->children); i != sd_list_end(anode->children);
  60. i = sd_list_iter_next(i))
  61. {
  62. sd_domnode_t* node = i->data;
  63. if (!strcmp(node->name, "nocleanup")) {
  64. this->config.nocleanup = atoi(node->value);
  65. if (this->config.nocleanup)
  66. sd_debug("deactivating log4c cleanup");
  67. }
  68. if (!strcmp(node->name, "bufsize")) {
  69. this->config.bufsize = parse_byte_size(node->value);
  70. if (this->config.bufsize)
  71. sd_debug("using fixed buffer size of %d bytes",
  72. this->config.bufsize);
  73. else
  74. sd_debug("using dynamic allocated buffer");
  75. }
  76. if (!strcmp(node->name, "debug")) {
  77. sd_domnode_t* level = sd_domnode_attrs_get(node, "level");
  78. if (level) {
  79. this->config.debug = atoi(level->value);
  80. sd_debug("activating log4c debugging. level = %d", this->config.debug);
  81. }
  82. }
  83. if (!strcmp(node->name, "reread")) {
  84. this->config.reread = atoi(node->value);
  85. sd_debug("log4crc reread is %d",this->config.reread);
  86. if (0 == this->config.reread)
  87. sd_debug("deactivating log4crc reread");
  88. }
  89. }
  90. return 0;
  91. }
  92. /******************************************************************************/
  93. static int category_load(log4c_rc_t* this, sd_domnode_t* anode)
  94. {
  95. sd_domnode_t* name = sd_domnode_attrs_get(anode, "name");
  96. sd_domnode_t* priority = sd_domnode_attrs_get(anode, "priority");
  97. sd_domnode_t* additivity = sd_domnode_attrs_get(anode, "additivity");
  98. sd_domnode_t* appender = sd_domnode_attrs_get(anode, "appender");
  99. log4c_category_t* cat = NULL;
  100. if (!name) {
  101. sd_error("attribute \"name\" is missing");
  102. return -1;
  103. }
  104. cat = log4c_category_get(name->value);
  105. if (priority)
  106. log4c_category_set_priority(
  107. cat, log4c_priority_to_int(priority->value));
  108. if (additivity) {
  109. if (!strcasecmp(additivity->value, "false")) {
  110. log4c_category_set_additivity(cat, 0);
  111. } else if (!strcasecmp(additivity->value, "true")) {
  112. log4c_category_set_additivity(cat, 1);
  113. } else {
  114. sd_error("additivity value is invalid : %s", additivity->value);
  115. }
  116. }
  117. if (appender)
  118. log4c_category_set_appender(
  119. cat, log4c_appender_get(appender->value));
  120. return 0;
  121. }
  122. /******************************************************************************/
  123. static int appender_load(log4c_rc_t* this, sd_domnode_t* anode)
  124. {
  125. sd_domnode_t* name = sd_domnode_attrs_get(anode, "name");
  126. sd_domnode_t* type = sd_domnode_attrs_get(anode, "type");
  127. sd_domnode_t* layout = sd_domnode_attrs_get(anode, "layout");
  128. log4c_appender_t* app = NULL;
  129. if (!name) {
  130. sd_error("attribute \"name\" is missing");
  131. return -1;
  132. }
  133. sd_debug("appender_load[name='%s'",
  134. (name->value ? name->value :"(not set)"));
  135. app = log4c_appender_get(name->value);
  136. if (type){
  137. sd_debug("appender type is '%s'",
  138. (type->value ? type->value: "(not set)"));
  139. log4c_appender_set_type(app, log4c_appender_type_get(type->value));
  140. #ifdef WITH_ROLLINGFILE
  141. if ( !strcasecmp(type->value, "rollingfile")) {
  142. rollingfile_udata_t *rfup = NULL;
  143. log4c_rollingpolicy_t *rollingpolicyp = NULL;
  144. sd_domnode_t *dom = NULL;
  145. const char *logdir = ".";
  146. const char *logprefix = "unnamed.log";
  147. const char *rollingpolicy_name = NULL;
  148. dom = sd_domnode_attrs_get(anode, "logdir");
  149. if (dom && dom->value) {
  150. logdir = dom->value;
  151. }
  152. dom = sd_domnode_attrs_get(anode, "prefix");
  153. if (dom && dom->value) {
  154. logprefix = dom->value;
  155. } else if (name && name->value) {
  156. logprefix = name->value;
  157. }
  158. dom = sd_domnode_attrs_get(anode, "rollingpolicy");
  159. if (dom && dom->value) {
  160. rollingpolicy_name = dom->value;
  161. }
  162. sd_debug("logdir='%s', prefix='%s', rollingpolicy='%s'",
  163. logdir, logprefix,
  164. rollingpolicy_name ? rollingpolicy_name : "(not set)");
  165. rfup = rollingfile_make_udata();
  166. rollingfile_udata_set_logdir(rfup, logdir);
  167. rollingfile_udata_set_files_prefix(rfup, logprefix);
  168. if (rollingpolicy_name && *rollingpolicy_name) {
  169. /* recover a rollingpolicy instance with this name */
  170. rollingpolicyp = log4c_rollingpolicy_get(rollingpolicy_name);
  171. /* connect that policy to this rollingfile appender conf */
  172. rollingfile_udata_set_policy(rfup, rollingpolicyp);
  173. log4c_appender_set_udata(app, rfup);
  174. /* allow the policy to initialize itself */
  175. log4c_rollingpolicy_init(rollingpolicyp, rfup);
  176. } else {
  177. /* no rollingpolicy specified, default to default sizewin */
  178. sd_debug("no rollingpolicy name specified--will default");
  179. }
  180. }
  181. #endif
  182. }
  183. if (layout)
  184. log4c_appender_set_layout(app, log4c_layout_get(layout->value));
  185. sd_debug("]");
  186. return 0;
  187. }
  188. /******************************************************************************/
  189. static int layout_load(log4c_rc_t* this, sd_domnode_t* anode)
  190. {
  191. sd_domnode_t* name = sd_domnode_attrs_get(anode, "name");
  192. sd_domnode_t* type = sd_domnode_attrs_get(anode, "type");
  193. log4c_layout_t* layout = NULL;
  194. if (!name) {
  195. sd_error("attribute \"name\" is missing");
  196. return -1;
  197. }
  198. layout = log4c_layout_get(name->value);
  199. if (type)
  200. log4c_layout_set_type(layout, log4c_layout_type_get(type->value));
  201. return 0;
  202. }
  203. #ifdef WITH_ROLLINGFILE
  204. /******************************************************************************/
  205. static int rollingpolicy_load(log4c_rc_t* this, sd_domnode_t* anode)
  206. {
  207. sd_domnode_t* name = sd_domnode_attrs_get(anode, "name");
  208. sd_domnode_t* type = sd_domnode_attrs_get(anode, "type");
  209. log4c_rollingpolicy_t* rpolicyp = NULL;
  210. long a_maxsize;
  211. sd_debug("rollingpolicy_load[");
  212. if (!name) {
  213. sd_error("attribute \"name\" is missing");
  214. return -1;
  215. }
  216. rpolicyp = log4c_rollingpolicy_get(name->value);
  217. if (type){
  218. log4c_rollingpolicy_set_type(rpolicyp,
  219. log4c_rollingpolicy_type_get(type->value));
  220. if (!strcasecmp(type->value, "sizewin")){
  221. sd_domnode_t* maxsize = sd_domnode_attrs_get(anode, "maxsize");
  222. sd_domnode_t* maxnum = sd_domnode_attrs_get(anode, "maxnum");
  223. rollingpolicy_sizewin_udata_t *sizewin_udatap = NULL;
  224. sd_debug("type='sizewin', maxsize='%s', maxnum='%s', "
  225. "rpolicyname='%s'",
  226. (maxsize && maxsize->value ? maxsize->value :"(not set)"),
  227. (maxnum && maxnum->value ? maxnum->value :"(not set)"),
  228. (name && name->value ? name->value :"(not set)"));
  229. /*
  230. * Get a new sizewin policy type and configure it.
  231. * Then attach it to the policy object.
  232. * Check to see if this policy already has a
  233. sw udata object. If so, leave as is except update
  234. the params
  235. */
  236. if ( !(sizewin_udatap = log4c_rollingpolicy_get_udata(rpolicyp))){
  237. sd_debug("creating new sizewin udata for this policy");
  238. sizewin_udatap = sizewin_make_udata();
  239. log4c_rollingpolicy_set_udata(rpolicyp,sizewin_udatap);
  240. a_maxsize = parse_byte_size(maxsize->value);
  241. if (a_maxsize)
  242. sizewin_udata_set_file_maxsize(sizewin_udatap, a_maxsize);
  243. else{
  244. sd_debug("When parsing %s a size of 0 was returned. Default size %d will be used",
  245. maxsize->value, ROLLINGPOLICY_SIZE_DEFAULT_MAX_FILE_SIZE);
  246. sizewin_udata_set_file_maxsize(sizewin_udatap, ROLLINGPOLICY_SIZE_DEFAULT_MAX_FILE_SIZE);
  247. }
  248. sizewin_udata_set_max_num_files(sizewin_udatap, atoi(maxnum->value));
  249. }else{
  250. sd_debug("policy already has a sizewin udata--just updating params");
  251. sizewin_udata_set_file_maxsize(sizewin_udatap, parse_byte_size(maxsize->value));
  252. sizewin_udata_set_max_num_files(sizewin_udatap, atoi(maxnum->value));
  253. /* allow the policy to initialize itself */
  254. log4c_rollingpolicy_init(rpolicyp,
  255. log4c_rollingpolicy_get_rfudata(rpolicyp));
  256. }
  257. }
  258. }
  259. sd_debug("]");
  260. return 0;
  261. }
  262. #endif
  263. /******************************************************************************/
  264. extern int log4c_rc_load(log4c_rc_t* this, const char* a_filename)
  265. {
  266. sd_list_iter_t* i = NULL;
  267. sd_domnode_t* node = NULL;
  268. sd_domnode_t* root_node = NULL;
  269. sd_debug("parsing file '%s'\n", a_filename);
  270. if (!this)
  271. return -1;
  272. root_node = sd_domnode_new(NULL, NULL);
  273. if (sd_domnode_load(root_node, a_filename) == -1) {
  274. sd_domnode_delete(root_node);
  275. return -1;
  276. }
  277. /* Check configuration file root node */
  278. if (strcmp(root_node->name, "log4c")) {
  279. sd_error("invalid root name %s", root_node->name);
  280. sd_domnode_delete(root_node);
  281. return -1;
  282. }
  283. /* Check configuration file revision */
  284. if ( (node = sd_domnode_attrs_get(root_node, "version")) != NULL)
  285. if (strcmp(version, node->value)) {
  286. sd_error("version mismatch: %s != %s", version, node->value);
  287. sd_domnode_delete(root_node);
  288. return -1;
  289. }
  290. /* backward compatibility. */
  291. if ( (node = sd_domnode_attrs_get(root_node, "cleanup")) != NULL) {
  292. sd_debug("attribute \"cleanup\" is deprecated");
  293. this->config.nocleanup = !atoi(node->value);
  294. }
  295. /* load configuration elements */
  296. for (i = sd_list_begin(root_node->children);
  297. i != sd_list_end(root_node->children);
  298. i = sd_list_iter_next(i))
  299. {
  300. sd_domnode_t* node = i->data;
  301. if (!strcmp(node->name, "category")) category_load(this, node);
  302. if (!strcmp(node->name, "appender")) appender_load(this, node);
  303. #ifdef WITH_ROLLINGFILE
  304. if (!strcmp(node->name, "rollingpolicy"))rollingpolicy_load(this, node);
  305. #endif
  306. if (!strcmp(node->name, "layout")) layout_load(this, node);
  307. if (!strcmp(node->name, "config")) config_load(this, node);
  308. }
  309. sd_domnode_delete(root_node);
  310. return 0;
  311. }
  312. /******************************************************************************/
  313. extern int log4c_load(const char* a_filename)
  314. {
  315. return log4c_rc_load(&__log4c_rc, a_filename);
  316. }