mirror of
https://git.haproxy.org/git/haproxy.git/
synced 2025-08-06 23:27:04 +02:00
MINOR: trace: postresolve sink names
A previous known limitation about traces was that parsing was performed on the fly, meaning that when using "sink" keyword, only sinks that were either internal or previously defined in the config could be used. Indeed, it was not possible to use a ring section defined AFTER the traces section when using the 'sink' keyword from traces. This limitation was also mentioned in the config file. Let's get rid of that limitation by implementing proper postparsing for the sink parameter in traces section. To do this, make use of the new sink_find_early() helper to start referencing sink by their names even if they don't exist yet (if they are about to be defined later in the config) Traces commands on the cli are not concerned by this change.
This commit is contained in:
parent
1bdf6e884a
commit
ed266589b6
@ -4357,11 +4357,9 @@ trace <source> <args...>
|
|||||||
section. Most of the time these will be errors and warnings, but certain
|
section. Most of the time these will be errors and warnings, but certain
|
||||||
incomplete commands might list permissible choices. This command is not meant
|
incomplete commands might list permissible choices. This command is not meant
|
||||||
for regular use, it will generally only be suggested by developers along
|
for regular use, it will generally only be suggested by developers along
|
||||||
complex debugging sessions. Note that these directives are parsed on the fly,
|
complex debugging sessions. It is important to keep in mind that depending on
|
||||||
so referencing a ring buffer that is only declared further will not work. It
|
the trace level and details, enabling traces can severely degrade the global
|
||||||
is important to keep in mind that depending on the trace level and details,
|
performance. Please refer to the management manual for the statements syntax.
|
||||||
enabling traces can severely degrade the global performance. Please refer to
|
|
||||||
the management manual for the statements syntax.
|
|
||||||
|
|
||||||
Example:
|
Example:
|
||||||
ring buf1
|
ring buf1
|
||||||
|
50
src/trace.c
50
src/trace.c
@ -439,6 +439,36 @@ static int trace_source_parse_verbosity(struct trace_source *src,
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* helper to get trace source sink name. Behavior is different during parsing
|
||||||
|
* time (<file> != NULL) and during runtime: this is to make sure that during
|
||||||
|
* parsing time sink name is properly postresolved
|
||||||
|
*
|
||||||
|
* Returns the sink pointer on success and NULL on error. <msg> will be set
|
||||||
|
* in case of error.
|
||||||
|
*/
|
||||||
|
static struct sink *_trace_get_sink(const char *name, char **msg,
|
||||||
|
const char *file, int line)
|
||||||
|
{
|
||||||
|
struct sink *sink = NULL;
|
||||||
|
|
||||||
|
if (file) {
|
||||||
|
/* only during parsing time */
|
||||||
|
sink = sink_find_early(name, "traces", file, line);
|
||||||
|
if (!sink) {
|
||||||
|
memprintf(msg, "Memory error while setting up sink '%s' \n", name);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
/* runtime */
|
||||||
|
sink = sink_find(name);
|
||||||
|
if (!sink) {
|
||||||
|
memprintf(msg, "No such trace sink '%s' \n", name);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return sink;
|
||||||
|
}
|
||||||
|
|
||||||
/* Parse a "trace" statement. Returns a severity as a LOG_* level and a status
|
/* Parse a "trace" statement. Returns a severity as a LOG_* level and a status
|
||||||
* message that may be delivered to the user, in <msg>. The message will be
|
* message that may be delivered to the user, in <msg>. The message will be
|
||||||
* nulled first and msg must be an allocated pointer. A null status message output
|
* nulled first and msg must be an allocated pointer. A null status message output
|
||||||
@ -447,7 +477,7 @@ static int trace_source_parse_verbosity(struct trace_source *src,
|
|||||||
* function may/will use the trash buffer as the storage for the response
|
* function may/will use the trash buffer as the storage for the response
|
||||||
* message so that the caller never needs to release anything.
|
* message so that the caller never needs to release anything.
|
||||||
*/
|
*/
|
||||||
static int trace_parse_statement(char **args, char **msg)
|
static int _trace_parse_statement(char **args, char **msg, const char *file, int line)
|
||||||
{
|
{
|
||||||
struct trace_source *orig_src, *src;
|
struct trace_source *orig_src, *src;
|
||||||
uint64_t *ev_ptr = NULL;
|
uint64_t *ev_ptr = NULL;
|
||||||
@ -663,6 +693,8 @@ static int trace_parse_statement(char **args, char **msg)
|
|||||||
src && src->sink == sink ? '*' : ' ',
|
src && src->sink == sink ? '*' : ' ',
|
||||||
sink->name, sink->desc);
|
sink->name, sink->desc);
|
||||||
}
|
}
|
||||||
|
if (file)
|
||||||
|
chunk_appendf(&trash, "(forward-declared sinks are not displayed here!)\n");
|
||||||
trash.area[trash.data] = 0;
|
trash.area[trash.data] = 0;
|
||||||
*msg = strdup(trash.area);
|
*msg = strdup(trash.area);
|
||||||
return LOG_WARNING;
|
return LOG_WARNING;
|
||||||
@ -671,11 +703,9 @@ static int trace_parse_statement(char **args, char **msg)
|
|||||||
if (strcmp(name, "none") == 0)
|
if (strcmp(name, "none") == 0)
|
||||||
sink = NULL;
|
sink = NULL;
|
||||||
else {
|
else {
|
||||||
sink = sink_find(name);
|
sink = _trace_get_sink(name, msg, file, line);
|
||||||
if (!sink) {
|
if (!sink)
|
||||||
memprintf(msg, "No such trace sink '%s'", name);
|
|
||||||
return LOG_ERR;
|
return LOG_ERR;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (src)
|
if (src)
|
||||||
@ -916,6 +946,14 @@ static int trace_parse_statement(char **args, char **msg)
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* same as _trace_parse_statement but when no file:line context is available
|
||||||
|
* (during runtime)
|
||||||
|
*/
|
||||||
|
static int trace_parse_statement(char **args, char **msg)
|
||||||
|
{
|
||||||
|
return _trace_parse_statement(args, msg, NULL, 0);
|
||||||
|
}
|
||||||
|
|
||||||
void _trace_parse_cmd(struct trace_source *src, int level, int verbosity)
|
void _trace_parse_cmd(struct trace_source *src, int level, int verbosity)
|
||||||
{
|
{
|
||||||
src->sink = sink_find("stderr");
|
src->sink = sink_find("stderr");
|
||||||
@ -1038,7 +1076,7 @@ static int cfg_parse_trace(char **args, int section_type, struct proxy *curpx,
|
|||||||
char *msg;
|
char *msg;
|
||||||
int severity;
|
int severity;
|
||||||
|
|
||||||
severity = trace_parse_statement(args, &msg);
|
severity = _trace_parse_statement(args, &msg, file, line);
|
||||||
if (msg) {
|
if (msg) {
|
||||||
if (severity >= LOG_NOTICE)
|
if (severity >= LOG_NOTICE)
|
||||||
ha_notice("parsing [%s:%d] : '%s': %s\n", file, line, args[0], msg);
|
ha_notice("parsing [%s:%d] : '%s': %s\n", file, line, args[0], msg);
|
||||||
|
Loading…
Reference in New Issue
Block a user