MEDIUM: errors: implement parsing context type

Create a parsing_ctx structure. This type is used to store information
about the current file/line parsed. A global context is created and
can be manipulated when haproxy is in STARTING mode. When starting is
over, the context is resetted and should not be accessed anymore.
This commit is contained in:
Amaury Denoyelle 2021-05-27 15:45:28 +02:00
parent 0a1cdccebd
commit 6af81f80fb
3 changed files with 59 additions and 3 deletions

View File

@ -60,12 +60,22 @@ enum {
};
void usermsgs_clr(void);
void usermsgs_clr(const char *prefix);
int usermsgs_empty(void);
const char *usermsgs_str(void);
/************ Error reporting functions ***********/
struct usermsgs_ctx {
const char *prefix; /* prefix of every output */
const char *file; /* related filename for config parsing */
int line; /* related line number for config parsing */
enum obj_type *obj; /* related proxy, server, ... */
};
void set_usermsgs_ctx(const char *file, int line, enum obj_type *obj);
void register_parsing_obj(enum obj_type *obj);
void reset_usermsgs_ctx(void);
/*
* Displays the message on stderr with the date and pid. Overrides the quiet
* mode during startup.

View File

@ -22,6 +22,10 @@ static struct ring *startup_logs = NULL;
#define USER_MESSAGES_BUFSIZE 1024
static THREAD_LOCAL struct buffer usermsgs_buf = BUF_NULL;
/* A thread local context used for stderr output via ha_alert/warning/notice/diag.
*/
static THREAD_LOCAL struct usermsgs_ctx usermsgs_ctx = { };
/* Put msg in usermsgs_buf.
*
* The message should not be terminated by a newline because this function
@ -49,13 +53,19 @@ static void usermsgs_put(const struct ist *msg)
}
}
/* Clear the messages log buffer. */
void usermsgs_clr(void)
/* Clear the user messages log buffer.
*
* <prefix> will set the local-thread context appended to every output
* following this call. It can be NULL if not necessary.
*/
void usermsgs_clr(const char *prefix)
{
if (likely(!b_is_null(&usermsgs_buf))) {
b_reset(&usermsgs_buf);
usermsgs_buf.area[0] = '\0';
}
usermsgs_ctx.prefix = prefix;
}
/* Check if the user messages buffer is empty. */
@ -73,6 +83,40 @@ const char *usermsgs_str(void)
return b_head(&usermsgs_buf);
}
/* Set thread-local context infos to prefix forthcoming stderr output during
* configuration parsing.
*
* <file> and <line> specify the location of the parsed configuration.
*
* <obj> can be of various types. If not NULL, the string prefix generated will
* depend on its type.
*/
void set_usermsgs_ctx(const char *file, int line, enum obj_type *obj)
{
usermsgs_ctx.file = file;
usermsgs_ctx.line = line;
usermsgs_ctx.obj = obj;
}
/* Set thread-local context infos to prefix forthcoming stderr output. It will
* be set as a complement to possibly already defined file/line.
*
* <obj> can be of various types. If not NULL, the string prefix generated will
* depend on its type.
*/
void register_parsing_obj(enum obj_type *obj)
{
usermsgs_ctx.obj = obj;
}
/* Reset thread-local context infos for stderr output. */
void reset_usermsgs_ctx(void)
{
usermsgs_ctx.file = NULL;
usermsgs_ctx.line = 0;
usermsgs_ctx.obj = NULL;
}
/* Generic function to display messages prefixed by a label */
static void print_message(const char *label, const char *fmt, va_list argp)
{

View File

@ -3380,6 +3380,8 @@ int main(int argc, char **argv)
}
global.mode &= ~MODE_STARTING;
reset_usermsgs_ctx();
/*
* That's it : the central polling loop. Run until we stop.
*/