category.c 6.22 KB
Newer Older
Hardy Simpson's avatar
Hardy Simpson committed
1
/*
Hardy Simpson's avatar
Hardy Simpson committed
2
 * This file is part of the zlog Library.
Hardy Simpson's avatar
Hardy Simpson committed
3
 *
Hardy Simpson's avatar
Hardy Simpson committed
4
 * Copyright (C) 2011 by Hardy Simpson <HardySimpson1984@gmail.com>
Hardy Simpson's avatar
Hardy Simpson committed
5
 *
6
 * Licensed under the LGPL v2.1, see the file COPYING in base directory.
Hardy Simpson's avatar
Hardy Simpson committed
7
 */
8
#include "fmacros.h"
Hardy Simpson's avatar
Hardy Simpson committed
9 10 11 12 13 14 15 16
#include <string.h>
#include <stdlib.h>
#include <errno.h>

#include "category.h"
#include "rule.h"
#include "zc_defs.h"

17
void zlog_category_profile(zlog_category_t *a_category, int flag)
Hardy Simpson's avatar
Hardy Simpson committed
18
{
19 20 21 22 23 24 25
	int i;
	zlog_rule_t *a_rule;

	zc_assert(a_category,);
	zc_profile(flag, "--category[%p][%s][%p]--",
			a_category,
			a_category->name,
26 27 28
			a_category->fit_rules);
	if (a_category->fit_rules) {
		zc_arraylist_foreach(a_category->fit_rules, i, a_rule) {
29 30 31 32 33
			zlog_rule_profile(a_rule, flag);
		}
	}
	return;
}
Hardy Simpson's avatar
Hardy Simpson committed
34

35 36 37 38
/*******************************************************************************/
void zlog_category_del(zlog_category_t * a_category)
{
	zc_assert(a_category,);
39
	if (a_category->fit_rules) zc_arraylist_del(a_category->fit_rules);
40 41
	free(a_category);
	zc_debug("zlog_category_del[%p]", a_category);
Hardy Simpson's avatar
Hardy Simpson committed
42 43 44
	return;
}

Hardy Simpson's avatar
Hardy Simpson committed
45 46 47 48 49 50 51 52 53 54 55 56
/* overlap one rule's level bitmap to cateogry,
 * so category can judge whether a log level will be output by itself
 * It is safe when configure is reloaded, when rule will be released an recreated
 */
static void zlog_cateogry_overlap_bitmap(zlog_category_t * a_category, zlog_rule_t *a_rule)
{
	int i;
	for(i = 0; i < sizeof(a_rule->level_bitmap); i++) {
		a_category->level_bitmap[i] |= a_rule->level_bitmap[i];
	}
}

57
static int zlog_category_obtain_rules(zlog_category_t * a_category, zc_arraylist_t * rules)
Hardy Simpson's avatar
Hardy Simpson committed
58 59 60
{
	int i;
	int count = 0;
61
	int fit = 0;
Hardy Simpson's avatar
Hardy Simpson committed
62
	zlog_rule_t *a_rule;
63
	zlog_rule_t *wastebin_rule = NULL;
Hardy Simpson's avatar
Hardy Simpson committed
64

Hardy Simpson's avatar
Hardy Simpson committed
65 66
	/* before set, clean last fit rules first */
	if (a_category->fit_rules) zc_arraylist_del(a_category->fit_rules);
Hardy Simpson's avatar
Hardy Simpson committed
67

Hardy Simpson's avatar
Hardy Simpson committed
68 69
	memset(a_category->level_bitmap, 0x00, sizeof(a_category->level_bitmap));

70 71
	a_category->fit_rules = zc_arraylist_new(NULL);
	if (!(a_category->fit_rules)) {
72
		zc_error("zc_arraylist_new fail");
Hardy Simpson's avatar
Hardy Simpson committed
73 74 75 76
		return -1;
	}

	/* get match rules from all rules */
77
	zc_arraylist_foreach(rules, i, a_rule) {
78 79
		fit = zlog_rule_match_category(a_rule, a_category->name);
		if (fit) {
Hardy Simpson's avatar
Hardy Simpson committed
80
			if (zc_arraylist_add(a_category->fit_rules, a_rule)) {
Hardy Simpson's avatar
Hardy Simpson committed
81
				zc_error("zc_arrylist_add fail");
Hardy Simpson's avatar
Hardy Simpson committed
82
				goto err;
Hardy Simpson's avatar
Hardy Simpson committed
83
			}
Hardy Simpson's avatar
Hardy Simpson committed
84
			zlog_cateogry_overlap_bitmap(a_category, a_rule);
Hardy Simpson's avatar
Hardy Simpson committed
85 86
			count++;
		}
87 88 89 90

		if (zlog_rule_is_wastebin(a_rule)) {
			wastebin_rule = a_rule;
		}
Hardy Simpson's avatar
Hardy Simpson committed
91 92
	}

93 94
	if (count == 0) {
		if (wastebin_rule) {
95
			zc_debug("category[%s], no match rules, use wastebin_rule", a_category->name);
Hardy Simpson's avatar
Hardy Simpson committed
96
			if (zc_arraylist_add(a_category->fit_rules, wastebin_rule)) {
97
				zc_error("zc_arrylist_add fail");
Hardy Simpson's avatar
Hardy Simpson committed
98
				goto err;
99
			}
Hardy Simpson's avatar
Hardy Simpson committed
100
			zlog_cateogry_overlap_bitmap(a_category, wastebin_rule);
101 102
			count++;
		} else {
103
			zc_debug("category[%s], no match rules & no wastebin_rule", a_category->name);
104 105
		}
	}
Hardy Simpson's avatar
Hardy Simpson committed
106

Hardy Simpson's avatar
Hardy Simpson committed
107 108 109 110 111
	return 0;
err:
	zc_arraylist_del(a_category->fit_rules);
	a_category->fit_rules = NULL;
	return -1;
Hardy Simpson's avatar
Hardy Simpson committed
112 113
}

114
zlog_category_t *zlog_category_new(const char *name, zc_arraylist_t * rules)
Hardy Simpson's avatar
Hardy Simpson committed
115
{
Hardy Simpson's avatar
Hardy Simpson committed
116
	size_t len;
117 118 119
	zlog_category_t *a_category;

	zc_assert(name, NULL);
120
	zc_assert(rules, NULL);
Hardy Simpson's avatar
Hardy Simpson committed
121

Hardy Simpson's avatar
Hardy Simpson committed
122 123 124 125 126
	len = strlen(name);
	if (len > sizeof(a_category->name) - 1) {
		zc_error("name[%s] too long", name);
		return NULL;
	}
127 128
	a_category = calloc(1, sizeof(zlog_category_t));
	if (!a_category) {
Hardy Simpson's avatar
Hardy Simpson committed
129 130 131
		zc_error("calloc fail, errno[%d]", errno);
		return NULL;
	}
Hardy Simpson's avatar
Hardy Simpson committed
132 133 134
	strcpy(a_category->name, name);
	a_category->name_len = len;
	if (zlog_category_obtain_rules(a_category, rules)) {
135
		zc_error("zlog_category_fit_rules fail");
Hardy Simpson's avatar
Hardy Simpson committed
136
		goto err;
Hardy Simpson's avatar
Hardy Simpson committed
137 138
	}

Hardy Simpson's avatar
Hardy Simpson committed
139 140 141 142 143
	zlog_category_profile(a_category, ZC_DEBUG);
	return a_category;
err:
	zlog_category_del(a_category);
	return NULL;
Hardy Simpson's avatar
Hardy Simpson committed
144
}
145 146 147 148 149 150 151 152 153 154 155 156
/*******************************************************************************/
/* update success: fit_rules 1, fit_rules_backup 1 */
/* update fail: fit_rules 0, fit_rules_backup 1 */
int zlog_category_update_rules(zlog_category_t * a_category, zc_arraylist_t * new_rules)
{
	zc_assert(a_category, -1);
	zc_assert(new_rules, -1);

	/* 1st, mv fit_rules fit_rules_backup */
	if (a_category->fit_rules_backup) zc_arraylist_del(a_category->fit_rules_backup);
	a_category->fit_rules_backup = a_category->fit_rules;
	a_category->fit_rules = NULL;
Hardy Simpson's avatar
Hardy Simpson committed
157 158 159

	memcpy(a_category->level_bitmap_backup, a_category->level_bitmap,
			sizeof(a_category->level_bitmap));
160 161
	
	/* 2nd, obtain new_rules to fit_rules */
Hardy Simpson's avatar
Hardy Simpson committed
162
	if (zlog_category_obtain_rules(a_category, new_rules)) {
163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183
		zc_error("zlog_category_obtain_rules fail");
		a_category->fit_rules = NULL;
		return -1;
	}

	/* keep the fit_rules_backup not change, return */
	return 0;
}

/* commit fail: fit_rules_backup != 0 */
/* commit success: fit_rules 1, fit_rules_backup 0 */
void zlog_category_commit_rules(zlog_category_t * a_category)
{
	zc_assert(a_category,);
	if (!a_category->fit_rules_backup) {
		zc_warn("a_category->fit_rules_backup is NULL, never update before");
		return;
	}

	zc_arraylist_del(a_category->fit_rules_backup);
	a_category->fit_rules_backup = NULL;
Hardy Simpson's avatar
Hardy Simpson committed
184 185
	memset(a_category->level_bitmap_backup, 0x00,
			sizeof(a_category->level_bitmap_backup));
186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209
	return;
}

/* rollback fail: fit_rules_backup != 0 */
/* rollback success: fit_rules 1, fit_rules_backup 0 */
/* so whether update succes or not, make things back to old */
void zlog_category_rollback_rules(zlog_category_t * a_category)
{
	zc_assert(a_category,);
	if (!a_category->fit_rules_backup) {
		zc_warn("a_category->fit_rules_backup in NULL, never update before");
		return;
	}

	if (a_category->fit_rules) {
		/* update success, rm new and backup */
		zc_arraylist_del(a_category->fit_rules);
		a_category->fit_rules = a_category->fit_rules_backup;
		a_category->fit_rules_backup = NULL;
	} else {
		/* update fail, just backup */
		a_category->fit_rules = a_category->fit_rules_backup;
		a_category->fit_rules_backup = NULL;
	}
Hardy Simpson's avatar
Hardy Simpson committed
210 211 212 213 214 215

	memcpy(a_category->level_bitmap, a_category->level_bitmap_backup,
			sizeof(a_category->level_bitmap));
	memset(a_category->level_bitmap_backup, 0x00,
			sizeof(a_category->level_bitmap_backup));
	
216 217 218 219
	return; /* always success */
}

/*******************************************************************************/
Hardy Simpson's avatar
Hardy Simpson committed
220

221
int zlog_category_output(zlog_category_t * a_category, zlog_thread_t * a_thread)
Hardy Simpson's avatar
Hardy Simpson committed
222 223 224
{
	int i;
	int rc = 0;
Hardy Simpson's avatar
Hardy Simpson committed
225
	zlog_rule_t *a_rule;
Hardy Simpson's avatar
Hardy Simpson committed
226

Hardy Simpson's avatar
Hardy Simpson committed
227
	/* go through all match rules to output */
228
	zc_arraylist_foreach(a_category->fit_rules, i, a_rule) {
Hardy Simpson's avatar
Hardy Simpson committed
229
		rc = zlog_rule_output(a_rule, a_thread);
Hardy Simpson's avatar
Hardy Simpson committed
230 231
	}

Hardy Simpson's avatar
Hardy Simpson committed
232
	return rc;
Hardy Simpson's avatar
Hardy Simpson committed
233
}