|
@@ -28,6 +28,7 @@
|
28
|
28
|
#include <unistd.h>
|
29
|
29
|
#include <fcntl.h>
|
30
|
30
|
#include <stdio.h>
|
|
31
|
+#include <time.h>
|
31
|
32
|
#include <sys/types.h>
|
32
|
33
|
#include <sys/stat.h>
|
33
|
34
|
|
|
@@ -51,6 +52,9 @@
|
51
|
52
|
/**@ingroup log_facility */
|
52
|
53
|
#define LOG_MASTER 8
|
53
|
54
|
|
|
55
|
+#define PYFCGI_LOGGER_FIELD_MAX 24
|
|
56
|
+#define PYFCGI_LOGGER_FMT_PARSE_ERRSZ 64
|
|
57
|
+
|
54
|
58
|
#define SYSLOG_syslog syslog
|
55
|
59
|
#define SYSLOG_vsyslog vsyslog
|
56
|
60
|
#define SYSLOG_EMERG LOG_EMERG
|
|
@@ -61,8 +65,8 @@
|
61
|
65
|
#define SYSLOG_NOTICE LOG_NOTICE
|
62
|
66
|
#define SYSLOG_INFO LOG_INFO
|
63
|
67
|
#define SYSLOG_DEBUG LOG_DEBUG
|
64
|
|
-const short SYSLOG_LVLS[8] = {LOG_EMERG, LOG_ALERT, LOG_CRIT, LOG_ERR,
|
65
|
|
- LOG_WARNING, LOG_NOTICE, LOG_INFO, LOG_DEBUG};
|
|
68
|
+static const short SYSLOG_LVLS[8] = {LOG_EMERG, LOG_ALERT, LOG_CRIT, LOG_ERR,
|
|
69
|
+ LOG_WARNING, LOG_NOTICE, LOG_INFO, LOG_DEBUG};
|
66
|
70
|
|
67
|
71
|
#undef LOG_EMERG
|
68
|
72
|
#undef LOG_ALERT
|
|
@@ -116,7 +120,10 @@ const short SYSLOG_LVLS[8] = {LOG_EMERG, LOG_ALERT, LOG_CRIT, LOG_ERR,
|
116
|
120
|
#define PYFCGI_LOG_FRETRY 2
|
117
|
121
|
/**@brief Exit if failure
|
118
|
122
|
* @ingroup cong_logger_flags */
|
119
|
|
-#define PYFCG_LOG_FEXIT_ONFAIL 4
|
|
123
|
+#define PYFCGI_LOG_FEXIT_ONFAIL 4
|
|
124
|
+
|
|
125
|
+#define PYFCGI_LOGGER_TIME_FMT_DEFAULT "%F %T%z"
|
|
126
|
+
|
120
|
127
|
|
121
|
128
|
/**@brief Log level mask
|
122
|
129
|
* @ingroup conf_logger
|
|
@@ -125,6 +132,12 @@ const short SYSLOG_LVLS[8] = {LOG_EMERG, LOG_ALERT, LOG_CRIT, LOG_ERR,
|
125
|
132
|
typedef unsigned char logmask_t;
|
126
|
133
|
typedef unsigned char loglvl_t;
|
127
|
134
|
typedef struct pyfcgi_logger_s pyfcgi_logger_t;
|
|
135
|
+typedef struct pyfcgi_logger_format_s pyfcgi_logger_format_t;
|
|
136
|
+typedef struct pyfcgi_logger_fmt_field_s pyfcgi_logger_fmt_field_t;
|
|
137
|
+typedef union pyfcgi_logger_fmt_field_u pyfcgi_logger_fmt_value_t;
|
|
138
|
+typedef enum pyfcgi_logger_field_type pyfcgi_logger_field_type_e;
|
|
139
|
+typedef struct strftime_args_s strftime_args_t;
|
|
140
|
+typedef union pyfcgi_logger_field_args pyfcgi_logger_field_args_u;
|
128
|
141
|
|
129
|
142
|
/**@brief Logger configuration
|
130
|
143
|
* @ingroup conf_logger
|
|
@@ -166,8 +179,92 @@ struct pyfcgi_logger_s
|
166
|
179
|
size_t fmt_id;
|
167
|
180
|
};
|
168
|
181
|
|
|
182
|
+/**@defgroup conf_logger_format Logline format
|
|
183
|
+ * @ingroup conf_logger
|
|
184
|
+ * A small description langage allows to describe wanted logline format.
|
|
185
|
+ * A format is a string with special markup indicating fields. Fields markup
|
|
186
|
+ * are surrounded by '{' and '}' chr. This markup can be divided in multiple
|
|
187
|
+ * subfields separated by ':' chr, but the first field is always the field
|
|
188
|
+ * name.
|
|
189
|
+ *
|
|
190
|
+ * Valid fields are :
|
|
191
|
+ * - {datetime:SIZE:FMT} defines a format and a constant length for date
|
|
192
|
+ * string. By default %F %T%z ISO 8601 date format + time + tz
|
|
193
|
+ * see @ref PYFCGI_LOGGER_TIME_FMT_DEFAULT
|
|
194
|
+ * - {level} the loglevel (with a constant length of 7)
|
|
195
|
+ * - {facility} the log facility (constant length od 6)
|
|
196
|
+ * - {pid:SIZE} PID with a constant length for pid field
|
|
197
|
+ * - {ident} the defined ident (size is processed when set)
|
|
198
|
+ * - {msg} the log message (can only appears once)
|
|
199
|
+ *
|
|
200
|
+ * @note You can escape '{' and '}' by using '{{' and '}}'
|
|
201
|
+ * @note There is a maximum of 24 fields by format (see
|
|
202
|
+ * @note All fields can be abbreviate to one character
|
|
203
|
+ * @ref PYFCGI_LOGGER_FIELD_MAX )
|
|
204
|
+ */
|
|
205
|
+
|
|
206
|
+struct strftime_args_s
|
|
207
|
+{
|
|
208
|
+ //char **s; // field.buf_ptr
|
|
209
|
+ //size_t max; // field.len
|
|
210
|
+ char *format;
|
|
211
|
+ //const struct tm *tm; // fecthed each time
|
|
212
|
+};
|
|
213
|
+
|
|
214
|
+union pyfcgi_logger_field_args
|
|
215
|
+{
|
|
216
|
+ strftime_args_t datetime;
|
|
217
|
+};
|
|
218
|
+
|
|
219
|
+/**@brief Logger format field's type
|
|
220
|
+ * @ingroup conf_logger_format */
|
|
221
|
+enum pyfcgi_logger_field_type
|
|
222
|
+{
|
|
223
|
+ pyfcgi_logger_field_null = 0,
|
|
224
|
+ pyfcgi_logger_field_const = -1,
|
|
225
|
+ pyfcgi_logger_field_datetime = 1,
|
|
226
|
+ pyfcgi_logger_field_level = 2,
|
|
227
|
+ pyfcgi_logger_field_facility = 3,
|
|
228
|
+ pyfcgi_logger_field_pid = 4,
|
|
229
|
+ pyfcgi_logger_field_ppid = 5,
|
|
230
|
+ pyfcgi_logger_field_ident = 6,
|
|
231
|
+ pyfcgi_logger_field_msg = 7,
|
|
232
|
+};
|
|
233
|
+
|
|
234
|
+/**@brief Logger format field data
|
|
235
|
+ * @ingroup conf_logger_format */
|
|
236
|
+struct pyfcgi_logger_fmt_field_s
|
|
237
|
+{
|
|
238
|
+ pyfcgi_logger_field_type_e type;
|
|
239
|
+
|
|
240
|
+ short known_length;
|
|
241
|
+ size_t len;
|
|
242
|
+
|
|
243
|
+ /** @brief pointer on value (interpreted given field type) */
|
|
244
|
+ void *val;
|
|
245
|
+ pyfcgi_logger_field_args_u args;
|
|
246
|
+ /**@brief Points in prefix or sufix buffer */
|
|
247
|
+ char *buf_ptr;
|
|
248
|
+};
|
|
249
|
+
|
|
250
|
+/**@brief Logger format data
|
|
251
|
+ * @ingroup conf_logger_format */
|
|
252
|
+struct pyfcgi_logger_format_s
|
|
253
|
+{
|
|
254
|
+ /**@brief Stores data about fields */
|
|
255
|
+ pyfcgi_logger_fmt_field_t fields[PYFCGI_LOGGER_FIELD_MAX];
|
|
256
|
+ /**@brief Preallocated buffer for prefix & suffix */
|
|
257
|
+ char *buf;
|
|
258
|
+ /**@brief Message prefix */
|
|
259
|
+ char *prefix;
|
|
260
|
+ /**@brief Message suffix */
|
|
261
|
+ char *suffix;
|
|
262
|
+};
|
|
263
|
+
|
169
|
264
|
#include "conf.h"
|
170
|
265
|
|
|
266
|
+int pyfcgi_logger_init();
|
|
267
|
+
|
171
|
268
|
/**@brief Add a new logger
|
172
|
269
|
* @param char* filename
|
173
|
270
|
* @param logmask_t loglvl a mask indicating wich loglevels should be logged
|
|
@@ -181,10 +278,50 @@ int pyfcgi_logger_add(const char*, logmask_t, logmask_t, const char*);
|
181
|
278
|
* @param size_t* idx if not NULL, will contain the format index
|
182
|
279
|
* @return 0 if OK
|
183
|
280
|
*/
|
184
|
|
-int pyfcgi_logger_add_format(const char*, size_t*);
|
|
281
|
+int pyfcgi_logger_format_add(const char*, size_t*);
|
|
282
|
+
|
|
283
|
+/**@brief Parse a format string and populate corresponding
|
|
284
|
+ * @ref struct pyfgci_logger_format_s
|
|
285
|
+ * @param const char* fmt string
|
|
286
|
+ * @param pyfcgi_logger_format_t* fmt_data
|
|
287
|
+ * @return 0 if no errors
|
|
288
|
+ */
|
|
289
|
+int pyfcgi_logger_parse_format(const char*, pyfcgi_logger_format_t*);
|
|
290
|
+
|
|
291
|
+/**@brief Parse a field string and populate corresponding
|
|
292
|
+ * @ret struct pyfcgi_logger_field_s
|
|
293
|
+ * @param const char ** ptr on current format pointer
|
|
294
|
+ * @param char * if not NULL and parse error occurs, this string
|
|
295
|
+ * will be set
|
|
296
|
+ * @return 0 if no errors and 1 if parse error
|
|
297
|
+ */
|
|
298
|
+int pyfcgi_logger_parse_field(const char**, const char *,
|
|
299
|
+ pyfcgi_logger_fmt_field_t*,
|
|
300
|
+ char[PYFCGI_LOGGER_FMT_PARSE_ERRSZ]);
|
|
301
|
+
|
|
302
|
+/**@brief Given a field pointer return the size option incrementing
|
|
303
|
+ * ptr
|
|
304
|
+ * @warning do not check if the next character is OK, the caller has to
|
|
305
|
+ * do it
|
|
306
|
+ * @param char** pointer on format
|
|
307
|
+ * @param size_t* size if found will be set to size option. if not found set to
|
|
308
|
+ * 0
|
|
309
|
+ * @return 0 if no error
|
|
310
|
+ */
|
|
311
|
+int pyfcgi_logger_parse_field_sz(const char**, size_t*);
|
|
312
|
+
|
|
313
|
+/**@brief Alloc memory by parsing & strdup the strftime format found
|
|
314
|
+ * in field. If not found use default format
|
|
315
|
+ * @note set the @ref struct pyfcgi_logger_fmt_field_s.args field
|
|
316
|
+ * @param const char** ptr
|
|
317
|
+ * @param char** format
|
|
318
|
+ * @return
|
|
319
|
+ */
|
|
320
|
+int pyfcgi_logger_parse_field_dtfmt(const char**, char**);
|
|
321
|
+
|
185
|
322
|
|
186
|
323
|
/**@brief Open a logger
|
187
|
|
- * @param pyfcgi_logger_t*
|
|
324
|
+ * @param pyfcgi_logger_t
|
188
|
325
|
* @return 0 if no errors
|
189
|
326
|
*/
|
190
|
327
|
int pyfcgi_logger_open(pyfcgi_logger_t*);
|