Skip to content

Add syslog-ng visibility into perf stackdumps #433

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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