2 // Copyright (c) 2010-2017 Intel Corporation
4 // Licensed under the Apache License, Version 2.0 (the "License");
5 // you may not use this file except in compliance with the License.
6 // You may obtain a copy of the License at
8 // http://www.apache.org/licenses/LICENSE-2.0
10 // Unless required by applicable law or agreed to in writing, software
11 // distributed under the License is distributed on an "AS IS" BASIS,
12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 // See the License for the specific language governing permissions and
14 // limitations under the License.
17 #include <sys/types.h>
21 #include <rte_cycles.h>
22 #include <rte_lcore.h>
23 #include <rte_ether.h>
33 #include "prox_compat.h"
35 static pthread_mutex_t file_mtx = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP;
36 int log_lvl = PROX_MAX_LOG_LVL;
37 static uint64_t tsc_off;
39 static int n_warnings = 0;
40 char last_warn[5][1024];
41 int get_n_warnings(void)
43 #if PROX_MAX_LOG_LVL < PROX_LOG_WARN
49 const char *get_warning(int i)
51 #if PROX_MAX_LOG_LVL < PROX_LOG_WARN
56 return last_warn[(n_warnings - 1 + i + 5) % 5];
59 static void store_warning(const char *warning)
61 prox_strncpy(last_warn[n_warnings % 5], warning, sizeof(last_warn[0]));
65 void plog_init(const char *log_name, int log_name_pid)
72 snprintf(buf, sizeof(buf), "%s-%u.log", "prox", getpid());
74 prox_strncpy(buf, "prox.log", sizeof(buf));
77 prox_strncpy(buf, log_name, sizeof(buf));
82 tsc_off = rte_rdtsc() + 2500000000;
92 int plog_set_lvl(int lvl)
94 if (lvl <= PROX_MAX_LOG_LVL) {
102 static void file_lock(void)
104 pthread_mutex_lock(&file_mtx);
107 static void file_unlock(void)
109 pthread_mutex_unlock(&file_mtx);
112 void file_print(const char *str)
121 static void plog_buf(const char* buf)
123 if (prox_cfg.logbuf) {
125 if (prox_cfg.logbuf_pos + strlen(buf) + 1 < prox_cfg.logbuf_size) {
126 memcpy(prox_cfg.logbuf + prox_cfg.logbuf_pos, buf, strlen(buf));
127 prox_cfg.logbuf_pos += strlen(buf);
135 /* ncurses never initialized */
142 static const char* lvl_to_str(int lvl, int always)
145 case PROX_LOG_ERR: return "error ";
146 case PROX_LOG_WARN: return "warn ";
147 case PROX_LOG_INFO: return always? "info " : "";
148 case PROX_LOG_DBG: return "debug ";
153 static int dump_pkt(char *dst, size_t dst_size, const struct rte_mbuf *mbuf)
155 const prox_rte_ether_hdr *peth = rte_pktmbuf_mtod(mbuf, const prox_rte_ether_hdr *);
156 const prox_rte_ipv4_hdr *dpip = (const prox_rte_ipv4_hdr *)(peth + 1);
157 const uint8_t *pkt_bytes = (const uint8_t *)peth;
158 const uint16_t len = rte_pktmbuf_pkt_len(mbuf);
161 if (peth->ether_type == ETYPE_IPv4)
162 str_len = snprintf(dst, dst_size, "pkt_len=%u, Eth=%x, Proto=%#06x",
163 len, peth->ether_type, dpip->next_proto_id);
165 str_len = snprintf(dst, dst_size, "pkt_len=%u, Eth=%x",
166 len, peth->ether_type);
168 for (uint16_t i = 0; i < len && i < DUMP_PKT_LEN && str_len < dst_size; ++i) {
170 str_len += snprintf(dst + str_len, dst_size - str_len, "\n%04x ", i);
172 else if (i % 8 == 0) {
173 str_len += snprintf(dst + str_len, dst_size - str_len, " ");
175 str_len += snprintf(dst + str_len, dst_size - str_len, "%02x ", pkt_bytes[i]);
177 if (str_len < dst_size)
178 snprintf(dst + str_len, dst_size - str_len, "\n");
182 static int vplog(int lvl, const char *format, va_list ap, const struct rte_mbuf *mbuf, int extended)
185 uint64_t hz, rtime_tsc, rtime_sec, rtime_usec;
191 if (format == NULL && mbuf == NULL)
196 hz = rte_get_tsc_hz();
197 rtime_tsc = rte_rdtsc() - tsc_off;
198 rtime_sec = rtime_tsc / hz;
199 rtime_usec = (rtime_tsc - rtime_sec * hz) / (hz / 1000000);
200 ret += snprintf(buf, sizeof(buf) - ret, "%2"PRIu64".%06"PRIu64" C%u %s%s",
201 rtime_sec, rtime_usec, rte_lcore_id(), lvl_to_str(lvl, 1), format? " " : "");
204 ret += snprintf(buf, sizeof(buf) - ret, "%s%s", lvl_to_str(lvl, 0), format? " " : "");
209 ret += vsnprintf(buf + ret, sizeof(buf) - ret, format, ap);
214 ret += dump_pkt(buf + ret, sizeof(buf) - ret, mbuf);
217 if (lvl == PROX_LOG_PANIC)
218 PROX_PANIC(1, "%s", buf);
222 if (lvl == PROX_LOG_WARN) {
228 #if PROX_MAX_LOG_LVL >= PROX_LOG_INFO
229 int plog_info(const char *fmt, ...)
235 ret = vplog(PROX_LOG_INFO, fmt, ap, NULL, 0);
240 int plogx_info(const char *fmt, ...)
246 ret = vplog(PROX_LOG_INFO, fmt, ap, NULL, 1);
251 int plogd_info(const struct rte_mbuf *mbuf, const char *fmt, ...)
257 ret = vplog(PROX_LOG_INFO, fmt, ap, mbuf, 0);
262 int plogdx_info(const struct rte_mbuf *mbuf, const char *fmt, ...)
268 ret = vplog(PROX_LOG_INFO, fmt, ap, mbuf, 1);
274 #if PROX_MAX_LOG_LVL >= PROX_LOG_ERR
275 int plog_err(const char *fmt, ...)
281 ret = vplog(PROX_LOG_ERR, fmt, ap, NULL, 0);
286 int plog_err_or_panic(int do_panic, const char *fmt, ...)
293 ret = vplog(PROX_LOG_PANIC, fmt, ap, NULL, 0);
297 ret = vplog(PROX_LOG_ERR, fmt, ap, NULL, 0);
303 int plogx_err(const char *fmt, ...)
309 ret = vplog(PROX_LOG_ERR, fmt, ap, NULL, 1);
314 int plogd_err(const struct rte_mbuf *mbuf, const char *fmt, ...)
320 ret = vplog(PROX_LOG_ERR, fmt, ap, mbuf, 1);
325 int plogdx_err(const struct rte_mbuf *mbuf, const char *fmt, ...)
331 ret = vplog(PROX_LOG_ERR, fmt, ap, mbuf, 1);
338 #if PROX_MAX_LOG_LVL >= PROX_LOG_WARN
339 int plog_warn(const char *fmt, ...)
345 ret = vplog(PROX_LOG_WARN, fmt, ap, NULL, 0);
350 int plogx_warn(const char *fmt, ...)
356 ret = vplog(PROX_LOG_WARN, fmt, ap, NULL, 1);
361 int plogd_warn(const struct rte_mbuf *mbuf, const char *fmt, ...)
367 ret = vplog(PROX_LOG_WARN, fmt, ap, mbuf, 0);
372 int plogdx_warn(const struct rte_mbuf *mbuf, const char *fmt, ...)
378 ret = vplog(PROX_LOG_WARN, fmt, ap, mbuf, 1);
384 #if PROX_MAX_LOG_LVL >= PROX_LOG_DBG
385 int plog_dbg(const char *fmt, ...)
391 ret = vplog(PROX_LOG_DBG, fmt, ap, NULL, 0);
396 int plogx_dbg(const char *fmt, ...)
402 ret = vplog(PROX_LOG_DBG, fmt, ap, NULL, 1);
407 int plogd_dbg(const struct rte_mbuf *mbuf, const char *fmt, ...)
413 ret = vplog(PROX_LOG_DBG, fmt, ap, mbuf, 0);
418 int plogdx_dbg(const struct rte_mbuf *mbuf, const char *fmt, ...)
424 ret = vplog(PROX_LOG_DBG, fmt, ap, mbuf, 1);