Line data Source code
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 0 : static int zlog_filter_lookup(const char *lookup)
35 : {
36 0 : for (int i = 0; i < zlog_filter_count; i++) {
37 0 : if (strncmp(lookup, zlog_filters[i], sizeof(zlog_filters[0]))
38 : == 0)
39 0 : return i;
40 : }
41 : return -1;
42 : }
43 :
44 0 : void zlog_filter_clear(void)
45 : {
46 0 : frr_with_mutex (&logfilterlock) {
47 0 : zlog_filter_count = 0;
48 : }
49 0 : }
50 :
51 0 : int zlog_filter_add(const char *filter)
52 : {
53 0 : frr_with_mutex (&logfilterlock) {
54 0 : if (zlog_filter_count >= ZLOG_FILTERS_MAX)
55 : return 1;
56 :
57 0 : if (zlog_filter_lookup(filter) != -1)
58 : /* Filter already present */
59 : return -1;
60 :
61 0 : strlcpy(zlog_filters[zlog_filter_count], filter,
62 : sizeof(zlog_filters[0]));
63 :
64 0 : 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 0 : zlog_filter_count++;
71 : }
72 0 : return 0;
73 : }
74 :
75 0 : int zlog_filter_del(const char *filter)
76 : {
77 0 : frr_with_mutex (&logfilterlock) {
78 0 : int found_idx = zlog_filter_lookup(filter);
79 0 : int last_idx = zlog_filter_count - 1;
80 :
81 0 : if (found_idx == -1)
82 : /* Didn't find the filter to delete */
83 0 : return -1;
84 :
85 : /* Adjust the filter array */
86 0 : memmove(zlog_filters[found_idx], zlog_filters[found_idx + 1],
87 0 : (last_idx - found_idx) * sizeof(zlog_filters[0]));
88 :
89 0 : zlog_filter_count--;
90 : }
91 0 : return 0;
92 : }
93 :
94 : /* Dump all filters to buffer, delimited by new line */
95 0 : int zlog_filter_dump(char *buf, size_t max_size)
96 : {
97 0 : int len = 0;
98 :
99 0 : frr_with_mutex (&logfilterlock) {
100 0 : for (int i = 0; i < zlog_filter_count; i++) {
101 0 : int ret;
102 :
103 0 : ret = snprintf(buf + len, max_size - len, " %s\n",
104 0 : zlog_filters[i]);
105 0 : len += ret;
106 0 : if ((ret < 0) || ((size_t)len >= max_size))
107 0 : return -1;
108 : }
109 : }
110 :
111 0 : return len;
112 : }
113 :
114 0 : static int search_buf(const char *buf, size_t len)
115 : {
116 0 : char *found = NULL;
117 :
118 0 : frr_with_mutex (&logfilterlock) {
119 0 : for (int i = 0; i < zlog_filter_count; i++) {
120 0 : found = memmem(buf, len, zlog_filters[i],
121 0 : strlen(zlog_filters[i]));
122 0 : if (found != NULL)
123 0 : return 0;
124 : }
125 : }
126 :
127 0 : return -1;
128 : }
129 :
130 0 : static void zlog_filterfile_fd(struct zlog_target *zt, struct zlog_msg *msgs[],
131 : size_t nmsgs)
132 0 : {
133 0 : struct zlog_msg *msgfilt[nmsgs];
134 0 : size_t i, o = 0;
135 0 : const char *text;
136 0 : size_t text_len;
137 :
138 0 : for (i = 0; i < nmsgs; i++) {
139 0 : if (zlog_msg_prio(msgs[i]) >= LOG_DEBUG) {
140 0 : text = zlog_msg_text(msgs[i], &text_len);
141 0 : if (search_buf(text, text_len) < 0)
142 0 : continue;
143 : }
144 0 : msgfilt[o++] = msgs[i];
145 : }
146 :
147 0 : if (o)
148 0 : zlog_fd(zt, msgfilt, o);
149 0 : }
150 :
151 190 : void zlog_filterfile_init(struct zlog_cfg_filterfile *zcf)
152 : {
153 190 : zlog_file_init(&zcf->parent);
154 190 : zcf->parent.zlog_wrap = zlog_filterfile_fd;
155 190 : }
156 :
157 0 : void zlog_filterfile_fini(struct zlog_cfg_filterfile *zcf)
158 : {
159 0 : zlog_file_fini(&zcf->parent);
160 0 : }
|