Imported Upstream version 16.11
[deb_dpdk.git] / lib / librte_eal / common / eal_common_log.c
1 /*-
2  *   BSD LICENSE
3  *
4  *   Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
5  *   All rights reserved.
6  *
7  *   Redistribution and use in source and binary forms, with or without
8  *   modification, are permitted provided that the following conditions
9  *   are met:
10  *
11  *     * Redistributions of source code must retain the above copyright
12  *       notice, this list of conditions and the following disclaimer.
13  *     * Redistributions in binary form must reproduce the above copyright
14  *       notice, this list of conditions and the following disclaimer in
15  *       the documentation and/or other materials provided with the
16  *       distribution.
17  *     * Neither the name of Intel Corporation nor the names of its
18  *       contributors may be used to endorse or promote products derived
19  *       from this software without specific prior written permission.
20  *
21  *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22  *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23  *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24  *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25  *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26  *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27  *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28  *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29  *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30  *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31  *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32  */
33
34 #include <stdio.h>
35 #include <stdint.h>
36 #include <stdarg.h>
37 #include <stdlib.h>
38
39 #include <rte_log.h>
40 #include <rte_per_lcore.h>
41
42 #include "eal_private.h"
43
44 /* global log structure */
45 struct rte_logs rte_logs = {
46         .type = ~0,
47         .level = RTE_LOG_DEBUG,
48         .file = NULL,
49 };
50
51 /* Stream to use for logging if rte_logs.file is NULL */
52 static FILE *default_log_stream;
53
54 /**
55  * This global structure stores some informations about the message
56  * that is currently being processed by one lcore
57  */
58 struct log_cur_msg {
59         uint32_t loglevel; /**< log level - see rte_log.h */
60         uint32_t logtype;  /**< log type  - see rte_log.h */
61 };
62
63  /* per core log */
64 static RTE_DEFINE_PER_LCORE(struct log_cur_msg, log_cur_msg);
65
66 /* default logs */
67
68 /* Change the stream that will be used by logging system */
69 int
70 rte_openlog_stream(FILE *f)
71 {
72         rte_logs.file = f;
73         return 0;
74 }
75
76 /* Set global log level */
77 void
78 rte_set_log_level(uint32_t level)
79 {
80         rte_logs.level = (uint32_t)level;
81 }
82
83 /* Get global log level */
84 uint32_t
85 rte_get_log_level(void)
86 {
87         return rte_logs.level;
88 }
89
90 /* Set global log type */
91 void
92 rte_set_log_type(uint32_t type, int enable)
93 {
94         if (enable)
95                 rte_logs.type |= type;
96         else
97                 rte_logs.type &= (~type);
98 }
99
100 /* Get global log type */
101 uint32_t
102 rte_get_log_type(void)
103 {
104         return rte_logs.type;
105 }
106
107 /* get the current loglevel for the message beeing processed */
108 int rte_log_cur_msg_loglevel(void)
109 {
110         return RTE_PER_LCORE(log_cur_msg).loglevel;
111 }
112
113 /* get the current logtype for the message beeing processed */
114 int rte_log_cur_msg_logtype(void)
115 {
116         return RTE_PER_LCORE(log_cur_msg).logtype;
117 }
118
119 /*
120  * Generates a log message The message will be sent in the stream
121  * defined by the previous call to rte_openlog_stream().
122  */
123 int
124 rte_vlog(uint32_t level, uint32_t logtype, const char *format, va_list ap)
125 {
126         int ret;
127         FILE *f = rte_logs.file;
128         if (f == NULL) {
129                 f = default_log_stream;
130                 if (f == NULL) {
131                         /*
132                          * Grab the current value of stderr here, rather than
133                          * just initializing default_log_stream to stderr. This
134                          * ensures that we will always use the current value
135                          * of stderr, even if the application closes and
136                          * reopens it.
137                          */
138                         f = stderr;
139                 }
140         }
141
142         if ((level > rte_logs.level) || !(logtype & rte_logs.type))
143                 return 0;
144
145         /* save loglevel and logtype in a global per-lcore variable */
146         RTE_PER_LCORE(log_cur_msg).loglevel = level;
147         RTE_PER_LCORE(log_cur_msg).logtype = logtype;
148
149         ret = vfprintf(f, format, ap);
150         fflush(f);
151         return ret;
152 }
153
154 /*
155  * Generates a log message The message will be sent in the stream
156  * defined by the previous call to rte_openlog_stream().
157  * No need to check level here, done by rte_vlog().
158  */
159 int
160 rte_log(uint32_t level, uint32_t logtype, const char *format, ...)
161 {
162         va_list ap;
163         int ret;
164
165         va_start(ap, format);
166         ret = rte_vlog(level, logtype, format, ap);
167         va_end(ap);
168         return ret;
169 }
170
171 /*
172  * Called by environment-specific initialization functions.
173  */
174 void
175 eal_log_set_default(FILE *default_log)
176 {
177         default_log_stream = default_log;
178
179 #if RTE_LOG_LEVEL >= RTE_LOG_DEBUG
180         RTE_LOG(NOTICE, EAL, "Debug logs available - lower performance\n");
181 #endif
182 }