1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147
|
// SPDX-License-Identifier: GPL-2.0-or-later
/*
* Logging - Filtered file log target
* Copyright (C) 2019 Cumulus Networks, Inc.
* Stephen Worley
*/
#include <zebra.h>
#include "frr_pthread.h"
#include "log.h"
static pthread_mutex_t logfilterlock = PTHREAD_MUTEX_INITIALIZER;
static char zlog_filters[ZLOG_FILTERS_MAX][ZLOG_FILTER_LENGTH_MAX + 1];
static uint8_t zlog_filter_count;
/*
* look for a match on the filter in the current filters,
* logfilterlock must be held
*/
static int zlog_filter_lookup(const char *lookup)
{
for (int i = 0; i < zlog_filter_count; i++) {
if (strncmp(lookup, zlog_filters[i], sizeof(zlog_filters[0]))
== 0)
return i;
}
return -1;
}
void zlog_filter_clear(void)
{
frr_with_mutex (&logfilterlock) {
zlog_filter_count = 0;
}
}
int zlog_filter_add(const char *filter)
{
frr_with_mutex (&logfilterlock) {
if (zlog_filter_count >= ZLOG_FILTERS_MAX)
return 1;
if (zlog_filter_lookup(filter) != -1)
/* Filter already present */
return -1;
strlcpy(zlog_filters[zlog_filter_count], filter,
sizeof(zlog_filters[0]));
if (zlog_filters[zlog_filter_count][0] == '\0')
/* Filter was either empty or didn't get copied
* correctly
*/
return -1;
zlog_filter_count++;
}
return 0;
}
int zlog_filter_del(const char *filter)
{
frr_with_mutex (&logfilterlock) {
int found_idx = zlog_filter_lookup(filter);
int last_idx = zlog_filter_count - 1;
if (found_idx == -1)
/* Didn't find the filter to delete */
return -1;
/* Adjust the filter array */
memmove(zlog_filters[found_idx], zlog_filters[found_idx + 1],
(last_idx - found_idx) * sizeof(zlog_filters[0]));
zlog_filter_count--;
}
return 0;
}
/* Dump all filters to buffer, delimited by new line */
int zlog_filter_dump(char *buf, size_t max_size)
{
int len = 0;
frr_with_mutex (&logfilterlock) {
for (int i = 0; i < zlog_filter_count; i++) {
int ret;
ret = snprintf(buf + len, max_size - len, " %s\n",
zlog_filters[i]);
len += ret;
if ((ret < 0) || ((size_t)len >= max_size))
return -1;
}
}
return len;
}
static int search_buf(const char *buf, size_t len)
{
char *found = NULL;
frr_with_mutex (&logfilterlock) {
for (int i = 0; i < zlog_filter_count; i++) {
found = memmem(buf, len, zlog_filters[i],
strlen(zlog_filters[i]));
if (found != NULL)
return 0;
}
}
return -1;
}
static void zlog_filterfile_fd(struct zlog_target *zt, struct zlog_msg *msgs[],
size_t nmsgs)
{
struct zlog_msg *msgfilt[nmsgs];
size_t i, o = 0;
const char *text;
size_t text_len;
for (i = 0; i < nmsgs; i++) {
if (zlog_msg_prio(msgs[i]) >= LOG_DEBUG) {
text = zlog_msg_text(msgs[i], &text_len);
if (search_buf(text, text_len) < 0)
continue;
}
msgfilt[o++] = msgs[i];
}
if (o)
zlog_fd(zt, msgfilt, o);
}
void zlog_filterfile_init(struct zlog_cfg_filterfile *zcf)
{
zlog_file_init(&zcf->parent);
zcf->parent.zlog_wrap = zlog_filterfile_fd;
}
void zlog_filterfile_fini(struct zlog_cfg_filterfile *zcf)
{
zlog_file_fini(&zcf->parent);
}
|