1 mike 1.1 /*
2 **==============================================================================
3 **
4 ** Open Management Infrastructure (OMI)
5 **
6 ** Copyright (c) Microsoft Corporation
7 **
8 ** Licensed under the Apache License, Version 2.0 (the "License"); you may not
9 ** use this file except in compliance with the License. You may obtain a copy
10 ** of the License at
11 **
12 ** http://www.apache.org/licenses/LICENSE-2.0
13 **
14 ** THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 ** KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED
16 ** WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,
17 ** MERCHANTABLITY OR NON-INFRINGEMENT.
18 **
19 ** See the Apache 2 License for the specific language governing permissions
20 ** and limitations under the License.
21 **
22 mike 1.1 **==============================================================================
23 */
24
25 #ifndef _omi_log_h
26 #define _omi_log_h
27
28 #include <common.h>
29 #include <stdarg.h>
30
31 BEGIN_EXTERNC
32
33 /*
34 **==============================================================================
35 **
36 ** Log
37 **
38 ** This interface supports writing of log entries to a flat file. The
39 ** following fragment shows how to use the logging facility.
40 **
41 ** Log_Open("/var/log/mylogfile");
42 ** ...
43 mike 1.1 ** Log_Put(LOG_ERROR, __FILE__, __LINE__, "bad sock=%u", sock);
44 ** Log_Put(LOG_INFO, __FILE__, __LINE__, "started");
45 ** Log_Put(LOG_DEBUG, __FILE__, __LINE__, "got this far");
46 ** ...
47 ** Log_Close();
48 **
49 ** The first argument of Log_Put() is the log level, which is one of
50 ** the following (in descending order of priority).
51 **
52 ** LOG_FATAL
53 ** LOG_ERROR
54 ** LOG_WARNING
55 ** LOG_INFO
56 ** LOG_DEBUG
57 **
58 ** Passing one of these to Log_SetLevel() affects which entries are
59 ** written to the log and which are ignored. For example, to log only
60 ** LOG_FATAL and LOG_ERROR levels, call Log_SetLevel as follows.
61 **
62 ** Log_SetLevel(LOG_ERROR);
63 **
64 mike 1.1 ** Afterwards, attempts to log anything below the LOG_ERROR level are
65 ** ignored. The default log level is LOG_WARNING.
66 **
67 ** The following macros simplify the writing of log entries by allowing
68 ** the caller to omit the level, __FILE__, and __LINE__ arguments.
69 **
70 ** LOGF() - LOG_FATAL
71 ** LOGE() - LOG_ERROR
72 ** LOGW() - LOG_WARNING
73 ** LOGI() - LOG_INFO
74 ** LOGD() - LOG_DEBUG
75 **
76 ** Using these macros reduces the code example above to this.
77 **
78 ** Log_Open("/var/log/mylogfile");
79 ** ...
80 ** LOGE(("bad sock=%u", sock));
81 ** LOGI(("started"));
82 ** LOGD(("got this far"));
83 ** ...
84 ** Log_Close();
85 mike 1.1 **
86 ** Notice the use of double parentheses (since macros do not support
87 ** varying argument lists).
88 **
89 ** Log entries have this format:
90 **
91 ** YYYY/MM/DD HH:MM:SS: LEVEL: FILE(LINE): message...
92 **
93 ** The code snippet above produces the following log entries.
94 **
95 ** 2010/01/01 12:43:26: ERROR: erp.c(10): bad sock=14
96 ** 2010/01/01 12:43:27: INFO: erp.c(11): started
97 ** 2010/01/01 12:43:28: DEBUG: erp.c(12): got this far
98 **
99 **==============================================================================
100 */
101
102 /* Log levels (default level is LOG_WARNING */
103 typedef enum _Log_Level
104 {
105 LOG_FATAL,
106 mike 1.1 LOG_ERROR,
107 LOG_WARNING,
108 LOG_INFO,
109 LOG_DEBUG
110 }
111 Log_Level;
112
113 /* Open 'path' for append (create if it does not exist). */
114 MI_Result Log_Open(
115 const MI_Char* path);
116
117 /* Open 'fd' for append. */
118 MI_Result Log_OpenFD(
119 int fd);
120
121 /* Open log and write log entries to standard error */
122 MI_Result Log_OpenStdErr();
123
124 /* Close the log file. */
125 void Log_Close();
126
127 mike 1.1 /* Set the log level (ignore all log writes below this level). */
128 void Log_SetLevel(
129 Log_Level level);
130
131 /* Get the current log level */
132 Log_Level Log_GetLevel();
133
134 /* Set the level from one of the following strings/numbers:
135 * FATAL/1
136 * ERROR/2
137 * WARNING/3
138 * INFO/4
139 * DEBUG/5
140 *
141 * Examples:
142 * Log_SetLevelFromString("DEBUG");
143 * Log_SetLevelFromString("3");
144 */
145 int Log_SetLevelFromString(const char* level);
146
147 /* Get a string representing the current log level, which will be one of the
148 mike 1.1 * following symbols: FATAL, ERROR, WARNING, INFO, DEBUG.
149 */
150 const char* Log_GetLevelString(Log_Level level);
151
152 PRINTF_FORMAT(4, 5)
153 int Log_Put(
154 Log_Level level,
155 const char* file,
156 MI_Uint32 line,
157 const MI_Char* format,
158 ...);
159
160 /* Va_List form of Log_Put. Returns '1' if output required,'0' otherwise*/
161 int Log_VPut(
162 Log_Level level,
163 const char* file,
164 MI_Uint32 line,
165 const MI_Char* format,
166 va_list ap);
167
168 /* Private internal function. */
169 mike 1.1 int __Log_Put1(
170 Log_Level level,
171 const char* file,
172 MI_Uint32 line);
173
174 /* Private internal function. */
175 PRINTF_FORMAT(1, 2)
176 void __Log_Put2(
177 const MI_Char* format,
178 ...);
179
180 /* Private internal function. */
181 PRINTF_FORMAT(1, 2)
182 void __Log_Put2_char(
183 const char* format,
184 ...);
185
186 /*
187 * This funtion appears as the false condition expression in the macros
188 * below. It suppresses the Windows 'conditional expression is constant'
189 * warning without the use of pragmas (which cannot be used in macros).
190 mike 1.1 */
191 INLINE int __LogFalse() { return 0; }
192
193 #define LOGF(ARGS) \
194 do \
195 { \
196 if (__Log_Put1(LOG_FATAL, __FILE__, __LINE__)) \
197 __Log_Put2 ARGS; \
198 } \
199 while (__LogFalse())
200
201 #define LOGE(ARGS) \
202 do \
203 { \
204 if (__Log_Put1(LOG_ERROR, __FILE__, __LINE__)) \
205 __Log_Put2 ARGS; \
206 } \
207 while (__LogFalse())
208
209 #define LOGW(ARGS) \
210 do \
211 mike 1.1 { \
212 if (__Log_Put1(LOG_WARNING, __FILE__, __LINE__)) \
213 __Log_Put2 ARGS; \
214 } \
215 while (__LogFalse())
216
217 #define LOGI(ARGS) \
218 do \
219 { \
220 if (__Log_Put1(LOG_INFO, __FILE__, __LINE__)) \
221 __Log_Put2 ARGS; \
222 } \
223 while (__LogFalse())
224
225 #define LOGD(ARGS) \
226 do \
227 { \
228 if (__Log_Put1(LOG_DEBUG, __FILE__, __LINE__)) \
229 __Log_Put2 ARGS; \
230 } \
231 while (__LogFalse())
232 mike 1.1
233 #define LOGF_CHAR(ARGS) \
234 do \
235 { \
236 if (__Log_Put1(LOG_FATAL, __FILE__, __LINE__)) \
237 __Log_Put2_char ARGS; \
238 } \
239 while (__LogFalse())
240
241 #define LOGE_CHAR(ARGS) \
242 do \
243 { \
244 if (__Log_Put1(LOG_ERROR, __FILE__, __LINE__)) \
245 __Log_Put2_char ARGS; \
246 } \
247 while (__LogFalse())
248
249 #define LOGW_CHAR(ARGS) \
250 do \
251 { \
252 if (__Log_Put1(LOG_WARNING, __FILE__, __LINE__)) \
253 mike 1.1 __Log_Put2_char ARGS; \
254 } \
255 while (__LogFalse())
256
257 #define LOGI_CHAR(ARGS) \
258 do \
259 { \
260 if (__Log_Put1(LOG_INFO, __FILE__, __LINE__)) \
261 __Log_Put2_char ARGS; \
262 } \
263 while (__LogFalse())
264
265 #define LOGD_CHAR(ARGS) \
266 do \
267 { \
268 if (__Log_Put1(LOG_DEBUG, __FILE__, __LINE__)) \
269 __Log_Put2_char ARGS; \
270 } \
271 while (__LogFalse())
272
273 END_EXTERNC
274 mike 1.1
275 #endif /* _omi_log_h */
|