]>
Commit | Line | Data |
---|---|---|
1c408628 DL |
1 | /* |
2 | * Logging - Filtered file log target | |
3 | * Copyright (C) 2019 Cumulus Networks, Inc. | |
4 | * Stephen Worley | |
5 | * | |
6 | * This program is free software; you can redistribute it and/or modify it | |
7 | * under the terms of the GNU General Public License as published by the Free | |
8 | * Software Foundation; either version 2 of the License, or (at your option) | |
9 | * any later version. | |
10 | * | |
11 | * This program is distributed in the hope that it will be useful, but WITHOUT | |
12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
13 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | |
14 | * more details. | |
15 | * | |
16 | * You should have received a copy of the GNU General Public License along | |
17 | * with this program; see the file COPYING; if not, write to the Free Software | |
18 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | |
19 | */ | |
20 | ||
21 | #include <zebra.h> | |
22 | ||
23 | #include "frr_pthread.h" | |
24 | #include "log.h" | |
25 | ||
26 | static pthread_mutex_t logfilterlock = PTHREAD_MUTEX_INITIALIZER; | |
27 | static char zlog_filters[ZLOG_FILTERS_MAX][ZLOG_FILTER_LENGTH_MAX + 1]; | |
28 | static uint8_t zlog_filter_count; | |
29 | ||
30 | /* | |
31 | * look for a match on the filter in the current filters, | |
32 | * logfilterlock must be held | |
33 | */ | |
34 | static int zlog_filter_lookup(const char *lookup) | |
35 | { | |
36 | for (int i = 0; i < zlog_filter_count; i++) { | |
37 | if (strncmp(lookup, zlog_filters[i], sizeof(zlog_filters[0])) | |
38 | == 0) | |
39 | return i; | |
40 | } | |
41 | return -1; | |
42 | } | |
43 | ||
44 | void zlog_filter_clear(void) | |
45 | { | |
cb1991af | 46 | frr_with_mutex (&logfilterlock) { |
1c408628 DL |
47 | zlog_filter_count = 0; |
48 | } | |
49 | } | |
50 | ||
51 | int zlog_filter_add(const char *filter) | |
52 | { | |
cb1991af | 53 | frr_with_mutex (&logfilterlock) { |
1c408628 DL |
54 | if (zlog_filter_count >= ZLOG_FILTERS_MAX) |
55 | return 1; | |
56 | ||
57 | if (zlog_filter_lookup(filter) != -1) | |
58 | /* Filter already present */ | |
59 | return -1; | |
60 | ||
61 | strlcpy(zlog_filters[zlog_filter_count], filter, | |
62 | sizeof(zlog_filters[0])); | |
63 | ||
64 | if (zlog_filters[zlog_filter_count][0] == '\0') | |
65 | /* Filter was either empty or didn't get copied | |
66 | * correctly | |
67 | */ | |
68 | return -1; | |
69 | ||
70 | zlog_filter_count++; | |
71 | } | |
72 | return 0; | |
73 | } | |
74 | ||
75 | int zlog_filter_del(const char *filter) | |
76 | { | |
cb1991af | 77 | frr_with_mutex (&logfilterlock) { |
1c408628 DL |
78 | int found_idx = zlog_filter_lookup(filter); |
79 | int last_idx = zlog_filter_count - 1; | |
80 | ||
81 | if (found_idx == -1) | |
82 | /* Didn't find the filter to delete */ | |
83 | return -1; | |
84 | ||
85 | /* Adjust the filter array */ | |
86 | memmove(zlog_filters[found_idx], zlog_filters[found_idx + 1], | |
87 | (last_idx - found_idx) * sizeof(zlog_filters[0])); | |
88 | ||
89 | zlog_filter_count--; | |
90 | } | |
91 | return 0; | |
92 | } | |
93 | ||
94 | /* Dump all filters to buffer, delimited by new line */ | |
95 | int zlog_filter_dump(char *buf, size_t max_size) | |
96 | { | |
97 | int len = 0; | |
98 | ||
cb1991af | 99 | frr_with_mutex (&logfilterlock) { |
1c408628 DL |
100 | for (int i = 0; i < zlog_filter_count; i++) { |
101 | int ret; | |
102 | ||
103 | ret = snprintf(buf + len, max_size - len, " %s\n", | |
104 | zlog_filters[i]); | |
105 | len += ret; | |
106 | if ((ret < 0) || ((size_t)len >= max_size)) | |
107 | return -1; | |
108 | } | |
109 | } | |
110 | ||
111 | return len; | |
112 | } | |
113 | ||
8b94cb43 | 114 | static int search_buf(const char *buf, size_t len) |
1c408628 DL |
115 | { |
116 | char *found = NULL; | |
117 | ||
cb1991af | 118 | frr_with_mutex (&logfilterlock) { |
1c408628 | 119 | for (int i = 0; i < zlog_filter_count; i++) { |
8b94cb43 DL |
120 | found = memmem(buf, len, zlog_filters[i], |
121 | strlen(zlog_filters[i])); | |
1c408628 DL |
122 | if (found != NULL) |
123 | return 0; | |
124 | } | |
125 | } | |
126 | ||
127 | return -1; | |
128 | } | |
129 | ||
130 | static void zlog_filterfile_fd(struct zlog_target *zt, struct zlog_msg *msgs[], | |
131 | size_t nmsgs) | |
132 | { | |
133 | struct zlog_msg *msgfilt[nmsgs]; | |
134 | size_t i, o = 0; | |
8b94cb43 DL |
135 | const char *text; |
136 | size_t text_len; | |
1c408628 DL |
137 | |
138 | for (i = 0; i < nmsgs; i++) { | |
8b94cb43 DL |
139 | if (zlog_msg_prio(msgs[i]) >= LOG_DEBUG) { |
140 | text = zlog_msg_text(msgs[i], &text_len); | |
141 | if (search_buf(text, text_len) < 0) | |
142 | continue; | |
143 | } | |
1c408628 DL |
144 | msgfilt[o++] = msgs[i]; |
145 | } | |
146 | ||
147 | if (o) | |
148 | zlog_fd(zt, msgfilt, o); | |
149 | } | |
150 | ||
151 | void zlog_filterfile_init(struct zlog_cfg_filterfile *zcf) | |
152 | { | |
153 | zlog_file_init(&zcf->parent); | |
154 | zcf->parent.zlog_wrap = zlog_filterfile_fd; | |
155 | } | |
156 | ||
157 | void zlog_filterfile_fini(struct zlog_cfg_filterfile *zcf) | |
158 | { | |
159 | zlog_file_fini(&zcf->parent); | |
160 | } |