Skip to content

Commit

Permalink
Merge pull request #433 from bazsi/add-syslog-ng-visibility-into-perf…
Browse files Browse the repository at this point in the history
…-stackdumps

Add syslog-ng visibility into perf stackdumps
  • Loading branch information
MrAnno authored Feb 11, 2025
2 parents 89dd4a1 + 45743a4 commit 9cd89bf
Show file tree
Hide file tree
Showing 23 changed files with 500 additions and 35 deletions.
1 change: 1 addition & 0 deletions cmake/syslog-ng-config.h.in
Original file line number Diff line number Diff line change
Expand Up @@ -106,3 +106,4 @@
#cmakedefine01 SYSLOG_NG_HAVE_SO_MEMINFO
#cmakedefine01 SYSLOG_NG_ENABLE_AFSOCKET_MEMINFO_METRICS
#cmakedefine01 SYSLOG_NG_HAVE_IV_WORK_POOL_SUBMIT_CONTINUATION
#cmakedefine01 SYSLOG_NG_ENABLE_PERF
18 changes: 18 additions & 0 deletions configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -266,6 +266,10 @@ AC_ARG_ENABLE(ebpf,
[ --enable-ebpf Enable support for loading of eBPF programs (default: no)]
,,enable_ebpf="no")

AC_ARG_ENABLE(perf,
[ --enable-perf Enable support for the Linux perf tool (default: auto)]
,,enable_perf="auto")

AC_ARG_ENABLE(gcov,
[ --enable-gcov Enable coverage profiling (default: no)]
,,enable_gcov="no")
Expand Down Expand Up @@ -466,6 +470,7 @@ dnl Checks for programs.
AC_PROG_CC
AC_PROG_CC_C99
AM_PROG_CC_C_O
AM_PROG_AS
if test "x$ac_cv_prog_cc_c99" = "xno"; then
AC_MSG_ERROR([C99 standard compliant C compiler required. Try GCC 3.x or later.])
fi
Expand Down Expand Up @@ -2060,6 +2065,16 @@ if test "x$enable_ebpf" = "xyes"; then
AC_SUBST(BPF_CC)
fi

if test "x$enable_perf" = "xauto"; then
uname_s=`uname -s`
uname_m=`uname -m`
if test "$uname_s" = "Linux" -a "$uname_m" = "x86_64"; then
enable_perf="yes"
else
enable_perf="no"
fi
fi

dnl ***************************************************************************
dnl check if we have timezone variable in <time.h>
dnl ***************************************************************************
Expand Down Expand Up @@ -2243,6 +2258,7 @@ AC_DEFINE_UNQUOTED(ENABLE_IPV6, `enable_value $enable_ipv6`, [Enable IPv6 suppor
AC_DEFINE_UNQUOTED(ENABLE_TCP_WRAPPER, `enable_value $enable_tcp_wrapper`, [Enable TCP wrapper support])
AC_DEFINE_UNQUOTED(ENABLE_LINUX_CAPS, `enable_value $enable_linux_caps`, [Enable Linux capability management support])
AC_DEFINE_UNQUOTED(ENABLE_EBPF, `enable_value $enable_ebpf`, [Enable Linux eBPF support])
AC_DEFINE_UNQUOTED(ENABLE_PERF, `enable_value $enable_perf`, [Enable Linux perf support])
AC_DEFINE_UNQUOTED(ENABLE_ENV_WRAPPER, `enable_value $enable_env_wrapper`, [Enable environment wrapper support])
AC_DEFINE_UNQUOTED(ENABLE_SYSTEMD, `enable_value $enable_systemd`, [Enable systemd support])
AC_DEFINE_UNQUOTED(ENABLE_KAFKA, `enable_value $enable_kafka`, [Enable kafka support])
Expand All @@ -2259,6 +2275,7 @@ AM_CONDITIONAL(ENABLE_SUN_STREAMS, [test "$enable_sun_streams" = "yes"])
AM_CONDITIONAL(ENABLE_DARWIN_OSL, [test "$enable_darwin_osl" = "yes"])
AM_CONDITIONAL(ENABLE_OPENBSD_SYSTEM_SOURCE, [test "$enable_openbsd_system_source" = "yes"])
AM_CONDITIONAL(ENABLE_EBPF, [test "$enable_ebpf" = "yes"])
AM_CONDITIONAL(ENABLE_PERF, [test "$enable_perf" = "yes"])
AM_CONDITIONAL(ENABLE_PACCT, [test "$enable_pacct" = "yes"])
AM_CONDITIONAL(ENABLE_MONGODB, [test "$enable_mongodb" = "yes"])
AM_CONDITIONAL(ENABLE_SMTP, [test "$enable_smtp" = "yes"])
Expand Down Expand Up @@ -2414,6 +2431,7 @@ echo " Env wrapper support : ${enable_env_wrapper:=no}"
echo " systemd support : ${enable_systemd:=no} (unit dir: ${systemdsystemunitdir:=none})"
echo " systemd-journal support : ${with_systemd_journal:=no}"
echo " JSON support : $with_jsonc"
echo " perf support : ${enable_perf:=no}"
echo " Build options:"
echo " Generate manual pages : ${enable_manpages:=no}"
echo " Install manual pages : ${enable_manpages_install:=no}"
Expand Down
2 changes: 2 additions & 0 deletions lib/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ include lib/logthrsource/Makefile.am
include lib/logthrdest/Makefile.am
include lib/signal-slot-connector/Makefile.am
include lib/multi-line/Makefile.am
include lib/perf/Makefile.am
include lib/adt/Makefile.am

LSNG_RELEASE = $(shell echo @PACKAGE_VERSION@ | cut -d. -f1,2)
Expand Down Expand Up @@ -309,6 +310,7 @@ lib_libsyslog_ng_la_SOURCES = \
$(logthrsource_sources) \
$(logthrdest_sources) \
$(signal_slot_connector_sources) \
$(perf_sources) \
$(adt_sources)

lib_libsyslog_ng_la_CFLAGS = \
Expand Down
7 changes: 5 additions & 2 deletions lib/afinter.c
Original file line number Diff line number Diff line change
Expand Up @@ -414,7 +414,7 @@ static gboolean
afinter_sd_pre_config_init(LogPipe *s)
{
main_loop_worker_allocate_thread_space(1);
return TRUE;
return log_pipe_pre_config_init_method(s);
}

static gboolean
Expand Down Expand Up @@ -459,7 +459,10 @@ afinter_sd_post_config_init(LogPipe *s)
{
AFInterSourceDriver *self = (AFInterSourceDriver *) s;

return afinter_source_start_thread(self->source);
if (!afinter_source_start_thread(self->source))
return FALSE;

return log_pipe_post_config_init_method(s);
}

static gboolean
Expand Down
2 changes: 2 additions & 0 deletions lib/cfg-lexer.c
Original file line number Diff line number Diff line change
Expand Up @@ -393,6 +393,7 @@ cfg_lexer_init_include_level_buffer(CfgLexer *self, CfgIncludeLevel *level,
level->buffer.content = lexer_buffer;
level->buffer.content_length = lexer_buffer_len;
level->buffer.original_content = g_strdup(lexer_buffer);
level->buffer.original_lines = NULL;
}

gboolean
Expand Down Expand Up @@ -458,6 +459,7 @@ cfg_lexer_include_level_clear(CfgLexer *self, CfgIncludeLevel *level)
{
g_free(level->buffer.content);
g_free(level->buffer.original_content);
g_strfreev(level->buffer.original_lines);
}
memset(level, 0, sizeof(*level));
}
Expand Down
1 change: 1 addition & 0 deletions lib/cfg-lexer.h
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,7 @@ struct _CfgIncludeLevel
{
/* the lexer mutates content, so save it for error reporting */
gchar *original_content;
gchar **original_lines;
/* buffer for the lexer */
gchar *content;
gsize content_length;
Expand Down
29 changes: 22 additions & 7 deletions lib/cfg-source.c
Original file line number Diff line number Diff line change
Expand Up @@ -226,9 +226,13 @@ _extract_source_from_file_location(GString *result, const gchar *filename, const
}

static gboolean
_extract_source_from_buffer_location(GString *result, const gchar *buffer_content, const CFG_LTYPE *yylloc)
_extract_source_from_buffer_location(GString *result, CfgIncludeLevel *level, const CFG_LTYPE *yylloc)
{
gchar **lines = g_strsplit(buffer_content, "\n", yylloc->last_line + 1);
const gchar *buffer_content = level->buffer.original_content;
gchar **lines = level->buffer.original_lines;

if (!lines)
lines = level->buffer.original_lines = g_strsplit(buffer_content, "\n", 0);
gint num_lines = g_strv_length(lines);

if (num_lines <= yylloc->first_line)
Expand All @@ -244,10 +248,18 @@ _extract_source_from_buffer_location(GString *result, const gchar *buffer_conten

if (lineno == yylloc->first_line)
{
gint token_start = MIN(linelen, yylloc->first_column - 1);

if (yylloc->first_line == yylloc->last_line)
g_string_append_len(result, &line[MIN(linelen, yylloc->first_column-1)], yylloc->last_column - yylloc->first_column);
{
/* both last_column & first_column are 1 based, they cancel that out */
gint token_len = yylloc->last_column - yylloc->first_column;
if (token_start + token_len > linelen)
token_len = linelen - token_start;
g_string_append_len(result, &line[token_start], token_len);
}
else
g_string_append(result, &line[MIN(linelen, yylloc->first_column-1)]);
g_string_append(result, &line[token_start]);
}
else if (lineno < yylloc->last_line)
{
Expand All @@ -256,13 +268,16 @@ _extract_source_from_buffer_location(GString *result, const gchar *buffer_conten
}
else if (lineno == yylloc->last_line)
{
/* last_column is 1 based */
gint token_len = yylloc->last_column - 1;
if (token_len > linelen)
token_len = linelen;
g_string_append_c(result, ' ');
g_string_append_len(result, line, yylloc->last_column);
g_string_append_len(result, line, token_len);
}
}

exit:
g_strfreev(lines);
return TRUE;
}

Expand All @@ -279,7 +294,7 @@ cfg_source_extract_source_text(CfgLexer *lexer, const CFG_LTYPE *yylloc, GString
CFG_LTYPE buf_lloc = *yylloc;
cfg_lexer_undo_set_file_location(lexer, &buf_lloc);

return _extract_source_from_buffer_location(result, level->buffer.original_content, &buf_lloc);
return _extract_source_from_buffer_location(result, level, &buf_lloc);
}
else
g_assert_not_reached();
Expand Down
29 changes: 25 additions & 4 deletions lib/filterx/filterx-expr.c
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,13 @@
#include "mainloop.h"
#include "stats/stats-registry.h"
#include "stats/stats-cluster-single.h"
#include "perf/perf.h"

static inline gboolean
_extract_source_text(void)
{
return debug_flag || perf_is_enabled();
}

void
filterx_expr_set_location_with_text(FilterXExpr *self, CFG_LTYPE *lloc, const gchar *text)
Expand All @@ -36,8 +43,11 @@ filterx_expr_set_location_with_text(FilterXExpr *self, CFG_LTYPE *lloc, const gc
self->lloc = g_new0(CFG_LTYPE, 1);
*self->lloc = *lloc;

if (debug_flag && text)
self->expr_text = g_strdup(text);
if (_extract_source_text() && text && text != self->expr_text)
{
g_free(self->expr_text);
self->expr_text = g_strdup(text);
}
}

void
Expand All @@ -46,8 +56,9 @@ filterx_expr_set_location(FilterXExpr *self, CfgLexer *lexer, CFG_LTYPE *lloc)
if (!self->lloc)
self->lloc = g_new0(CFG_LTYPE, 1);
*self->lloc = *lloc;
if (debug_flag)
if (_extract_source_text())
{
g_free(self->expr_text);
GString *res = g_string_sized_new(0);
cfg_source_extract_source_text(lexer, lloc, res);
self->expr_text = g_string_free(res, FALSE);
Expand Down Expand Up @@ -110,7 +121,7 @@ _init_sc_key_name(FilterXExpr *self, gchar *buf, gsize buf_len)
gboolean
filterx_expr_init_method(FilterXExpr *self, GlobalConfig *cfg)
{
gchar buf[64];
gchar buf[256];

_init_sc_key_name(self, buf, sizeof(buf));
stats_lock();
Expand All @@ -123,6 +134,16 @@ filterx_expr_init_method(FilterXExpr *self, GlobalConfig *cfg)
stats_cluster_single_key_set(&sc_key, buf, labels, labels_len);
stats_register_counter(STATS_LEVEL3, &sc_key, SC_TYPE_SINGLE_VALUE, &self->eval_count);
stats_unlock();

if (perf_is_enabled())
{
if (self->expr_text)
g_snprintf(buf, sizeof(buf), "filterx::%s", self->expr_text);
else
g_snprintf(buf, sizeof(buf), "filterx::@%s", self->type);
self->eval = perf_generate_trampoline(self->eval, buf);
}

return TRUE;
}

Expand Down
8 changes: 4 additions & 4 deletions lib/filterx/filterx-grammar.ym
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,7 @@ _assign_location(FilterXExpr *expr, CfgLexer *lexer, CFG_LTYPE *lloc)
%type <node> comparison_operator
%type <node> arithmetic_operator
%type <node> expr_generator
%type <node> expr_generator_unchecked
%type <node> __expr_generator
%type <node> expr_plus_generator
%type <node> generator_function_call
%type <node> function_call
Expand Down Expand Up @@ -469,13 +469,13 @@ expr_value
;

expr_generator
: expr_generator_unchecked {
$$ = $1;
: __expr_generator {
CHECK_ERROR($1, @1, "error initializing generator expression");
$$ = _assign_location($1, lexer, &@1);
}
;

expr_generator_unchecked
__expr_generator
: dict_generator
| list_generator
| generator_function_call
Expand Down
16 changes: 15 additions & 1 deletion lib/gprocess.c
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
#include "messages.h"
#include "reloc.h"
#include "console.h"
#include "perf/perf.h"

#include <sys/types.h>
#include <sys/stat.h>
Expand Down Expand Up @@ -126,6 +127,7 @@ static struct
const gchar *cwd;
const gchar *caps;
gboolean enable_caps;
gboolean enable_perf;
gint argc;
gchar **argv;
gchar *argv_start;
Expand Down Expand Up @@ -719,6 +721,16 @@ g_process_enable_core(void)
}
}

static void
g_process_enable_perf(void)
{
if (process_opts.enable_perf || perf_autodetect())
{
if (!perf_enable())
console_printf("Error enabling Linux perf profiling support, maybe not compiled in using --enable-perf?");
}
}

/**
* g_process_format_pidfile_name:
* @buf: buffer to store the pidfile name
Expand Down Expand Up @@ -1425,6 +1437,7 @@ g_process_start(void)
}
g_process_enable_core();
g_process_change_dir();
g_process_enable_perf();
}


Expand Down Expand Up @@ -1554,7 +1567,8 @@ static GOptionEntry g_process_option_entries[] =
{ "no-caps", 0, G_OPTION_FLAG_NO_ARG, G_OPTION_ARG_CALLBACK, g_process_process_no_caps, "Disable managing Linux capabilities", NULL },
{ "pidfile", 'p', 0, G_OPTION_ARG_STRING, &process_opts.pidfile, "Set path to pid file", "<pidfile>" },
{ "enable-core", 0, 0, G_OPTION_ARG_NONE, &process_opts.core, "Enable dumping core files", NULL },
{ "fd-limit", 0, 0, G_OPTION_ARG_INT, &process_opts.fd_limit_min, "The minimum required number of fds", NULL },
{ "fd-limit", 0, 0, G_OPTION_ARG_INT, &process_opts.fd_limit_min, "The minimum required number of fds", NULL },
{ "perf-profiling", 0, 0, G_OPTION_ARG_NONE, &process_opts.enable_perf, "Enable Linux perf based profiling", NULL },
{ NULL, 0, 0, 0, NULL, NULL, NULL },
};

Expand Down
22 changes: 21 additions & 1 deletion lib/logpipe.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
#include "logpipe.h"
#include "cfg-tree.h"
#include "cfg-walker.h"
#include "perf/perf.h"

gboolean (*pipe_single_step_hook)(LogPipe *pipe, LogMessage *msg, const LogPathOptions *path_options);

Expand Down Expand Up @@ -146,6 +147,24 @@ log_pipe_clone_method(LogPipe *dst, const LogPipe *src)
log_pipe_set_options(dst, &src->options);
}

gboolean
log_pipe_pre_config_init_method(LogPipe *self)
{
return TRUE;
}

gboolean
log_pipe_post_config_init_method(LogPipe *self)
{
if ((self->flags & PIF_CONFIG_RELATED) && perf_is_enabled())
{
gchar buf[256];

self->queue = perf_generate_trampoline(self->queue, log_expr_node_format_location(self->expr_node, buf, sizeof(buf)));
}
return TRUE;
}

void
log_pipe_init_instance(LogPipe *self, GlobalConfig *cfg)
{
Expand All @@ -154,7 +173,8 @@ log_pipe_init_instance(LogPipe *self, GlobalConfig *cfg)
self->pipe_next = NULL;
self->persist_name = NULL;
self->plugin_name = NULL;

self->pre_config_init = log_pipe_pre_config_init_method;
self->post_config_init = log_pipe_post_config_init_method;
self->queue = log_pipe_forward_msg;
self->free_fn = log_pipe_free_method;
self->arcs = _arcs;
Expand Down
2 changes: 2 additions & 0 deletions lib/logpipe.h
Original file line number Diff line number Diff line change
Expand Up @@ -349,6 +349,8 @@ extern gboolean (*pipe_single_step_hook)(LogPipe *pipe, LogMessage *msg, const L
LogPipe *log_pipe_ref(LogPipe *self);
gboolean log_pipe_unref(LogPipe *self);
LogPipe *log_pipe_new(GlobalConfig *cfg);
gboolean log_pipe_pre_config_init_method(LogPipe *self);
gboolean log_pipe_post_config_init_method(LogPipe *self);
void log_pipe_init_instance(LogPipe *self, GlobalConfig *cfg);
void log_pipe_clone_method(LogPipe *dst, const LogPipe *src);
void log_pipe_forward_notify(LogPipe *self, gint notify_code, gpointer user_data);
Expand Down
Loading

0 comments on commit 9cd89bf

Please sign in to comment.