section. Most of the time these will be errors and warnings, but certain
incomplete commands might list permissible choices. This command is not meant
for regular use, it will generally only be suggested by developers along
- complex debugging sessions. Note that these directives are parsed on the fly,
- so referencing a ring buffer that is only declared further will not work. It
- is important to keep in mind that depending on the trace level and details,
- enabling traces can severely degrade the global performance. Please refer to
- the management manual for the statements syntax.
+ complex debugging sessions. It is important to keep in mind that depending on
+ the trace level and details, enabling traces can severely degrade the global
+ performance. Please refer to the management manual for the statements syntax.
Example:
ring buf1
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
* 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
* function may/will use the trash buffer as the storage for the response
* 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;
uint64_t *ev_ptr = NULL;
src && src->sink == sink ? '*' : ' ',
sink->name, sink->desc);
}
+ if (file)
+ chunk_appendf(&trash, "(forward-declared sinks are not displayed here!)\n");
trash.area[trash.data] = 0;
*msg = strdup(trash.area);
return LOG_WARNING;
if (strcmp(name, "none") == 0)
sink = NULL;
else {
- sink = sink_find(name);
- if (!sink) {
- memprintf(msg, "No such trace sink '%s'", name);
+ sink = _trace_get_sink(name, msg, file, line);
+ if (!sink)
return LOG_ERR;
- }
}
if (src)
}
+/* 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)
{
src->sink = sink_find("stderr");
char *msg;
int severity;
- severity = trace_parse_statement(args, &msg);
+ severity = _trace_parse_statement(args, &msg, file, line);
if (msg) {
if (severity >= LOG_NOTICE)
ha_notice("parsing [%s:%d] : '%s': %s\n", file, line, args[0], msg);