Skip to content

Commit 34b03d6

Browse files
Merge pull request #2940 from rabbitmq/support-journald-logging
Logging: Add journald support
2 parents 64f6c18 + 91583a0 commit 34b03d6

File tree

4 files changed

+226
-33
lines changed

4 files changed

+226
-33
lines changed

deps/rabbit/Makefile

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -133,13 +133,15 @@ APPS_DIR := $(CURDIR)/apps
133133
LOCAL_DEPS = sasl rabbitmq_prelaunch os_mon inets compiler public_key crypto ssl syntax_tools xmerl
134134

135135
BUILD_DEPS = rabbitmq_cli
136-
DEPS = ranch rabbit_common ra sysmon_handler stdout_formatter recon observer_cli osiris amqp10_common syslog
136+
DEPS = ranch rabbit_common ra sysmon_handler stdout_formatter recon observer_cli osiris amqp10_common syslog systemd
137137
TEST_DEPS = rabbitmq_ct_helpers rabbitmq_ct_client_helpers amqp_client meck proper
138138

139139
PLT_APPS += mnesia
140140

141141
dep_syslog = git https://github.com/schlagert/syslog 4.0.0
142142
dep_osiris = git https://github.com/rabbitmq/osiris master
143+
# TODO: Use systemd from Hex.pm, once there is a new post-0.6.0 release.
144+
dep_systemd = git https://github.com/hauleth/erlang-systemd 0ce748edffcb72bb028733e9ca4707cb30add853
143145

144146
define usage_xml_to_erl
145147
$(subst __,_,$(patsubst $(DOCS_DIR)/rabbitmq%.1.xml, src/rabbit_%_usage.erl, $(subst -,_,$(1))))

deps/rabbit/apps/rabbitmq_prelaunch/src/rabbit_prelaunch_early_logging.erl

Lines changed: 78 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,13 @@
1515
default_formatter/1,
1616
default_console_formatter/1,
1717
default_file_formatter/1,
18+
default_journald_formatter/1,
1819
default_syslog_formatter/1,
1920
enable_quick_dbg/1,
2021
use_colored_logging/0,
2122
use_colored_logging/1,
22-
translate_formatter_conf/2]).
23+
translate_formatter_conf/2,
24+
translate_journald_fields_conf/2]).
2325
-export([filter_log_event/2]).
2426

2527
-ifdef(TEST).
@@ -121,6 +123,10 @@ default_console_formatter(Context) ->
121123
default_file_formatter(Context) ->
122124
default_formatter(Context#{output_supports_colors => false}).
123125

126+
default_journald_formatter(_Context) ->
127+
{rabbit_logger_text_fmt, #{prefix_format => [],
128+
use_colors => false}}.
129+
124130
default_syslog_formatter(Context) ->
125131
{Module, Config} = default_file_formatter(Context),
126132
case Module of
@@ -155,8 +161,8 @@ enable_quick_dbg(#{dbg_output := Output, dbg_mods := Mods}) ->
155161
{rabbit_logger_text_fmt, formatter_plaintext_conf()} |
156162
{rabbit_logger_json_fmt, formatter_json_conf()}.
157163
%% @doc
158-
%% Called from the Cuttlefish schema to derive the actual configuration from
159-
%% several Cuttlefish variables.
164+
%% Called from the Cuttlefish schema to derive the actual formatter
165+
%% configuration from several Cuttlefish variables.
160166

161167
translate_formatter_conf(Var, Conf) when is_list(Var) ->
162168
try
@@ -404,7 +410,7 @@ translate_json_formatter_conf(Var, Conf, GenericConfig) ->
404410

405411
-spec parse_json_field_mapping(string()) -> json_field_map().
406412
%% @doc
407-
%% Parses the field_map pattern.
413+
%% Parses the JSON formatter field_map pattern.
408414
%%
409415
%% The pattern is of the form: `time:ts level msg *:-'.
410416
%%
@@ -496,5 +502,73 @@ parse_json_verbosity_mapping([], #{'$REST' := Default} = Mapping) ->
496502
parse_json_verbosity_mapping([], Mapping) ->
497503
Mapping.
498504

505+
-spec translate_journald_fields_conf(string(), cuttlefish_conf:conf()) ->
506+
proplists:proplist().
507+
%% @doc
508+
%% Called from the Cuttlefish schema to create the actual journald handler
509+
%% configuration.
510+
511+
translate_journald_fields_conf(Var, Conf) when is_list(Var) ->
512+
try
513+
RawFieldMapping = cuttlefish:conf_get(Var, Conf),
514+
parse_journald_field_mapping(RawFieldMapping)
515+
catch
516+
Class:Reason:Stacktrace ->
517+
?LOG_ERROR(
518+
rabbit_prelaunch_errors:format_exception(
519+
Class, Reason, Stacktrace),
520+
#{domain => ?RMQLOG_DOMAIN_PRELAUNCH}),
521+
throw({configuration_translation_failure, Reason})
522+
end.
523+
524+
-spec parse_journald_field_mapping(string()) ->
525+
[atom() | {atom(), atom()}].
526+
%% @doc
527+
%% Parses the journald fields pattern.
528+
%%
529+
%% The pattern is of the form: `SYSLOG_IDENTIFIER="rabbitmq-server" pid
530+
%% CODE_FILE=file'.
531+
%%
532+
%% `SYSLOG_IDENTIFIER="rabbitmq"' means the `SYSLOG_IDENTIFIER' field should
533+
%% be set to the string `rabbitmq-server'.
534+
%%
535+
%% `pid' means that field should be kept as-is.
536+
%%
537+
%% `CODE_FILE=file' means the `CODE_FILE' field should be set to the value of
538+
%% the `pid' field.
539+
540+
parse_journald_field_mapping(RawMapping) ->
541+
parse_journald_field_mapping(string:split(RawMapping, " ", all), []).
542+
543+
parse_journald_field_mapping([Entry | Rest], Mapping) ->
544+
Mapping1 = case string:split(Entry, "=", leading) of
545+
[[$_ | _], _] ->
546+
throw({bad_journald_mapping,
547+
leading_underscore_forbidden,
548+
Entry});
549+
[Name, Value] ->
550+
case re:run(Name, "^[A-Z0-9_]+$", [{capture, none}]) of
551+
match ->
552+
ReOpts = [{capture, all_but_first, list}],
553+
case re:run(Value, "^\"(.+)\"$", ReOpts) of
554+
{match, [Data]} ->
555+
[{Name, Data} | Mapping];
556+
nomatch ->
557+
Field = list_to_atom(Value),
558+
[{Name, Field} | Mapping]
559+
end;
560+
nomatch ->
561+
throw({bad_journald_mapping,
562+
name_with_invalid_characters,
563+
Entry})
564+
end;
565+
[FieldS] ->
566+
Field = list_to_atom(FieldS),
567+
[Field | Mapping]
568+
end,
569+
parse_journald_field_mapping(Rest, Mapping1);
570+
parse_journald_field_mapping([], Mapping) ->
571+
lists:reverse(Mapping).
572+
499573
levels() ->
500574
[debug, info, notice, warning, error, critical, alert, emergency].

deps/rabbit/priv/schema/rabbit.schema

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1304,6 +1304,21 @@ end}.
13041304
rabbit_prelaunch_early_logging:translate_formatter_conf("log.exchange.formatter", Conf)
13051305
end}.
13061306

1307+
{mapping, "log.journald", "rabbit.log.journald.enabled", [
1308+
{datatype, {enum, [true, false]}}
1309+
]}.
1310+
{mapping, "log.journald.level", "rabbit.log.journald.level", [
1311+
{datatype, {enum, [debug, info, notice, warning, error, critical, alert, emergency, none]}}
1312+
]}.
1313+
{mapping, "log.journald.fields", "rabbit.log.journald.fields", [
1314+
{default, "SYSLOG_IDENTIFIER=\"rabbitmq-server\" syslog_timestamp syslog_pid priority ERL_PID=pid CODE_FILE=file CODE_LINE=line CODE_MFA=mfa"},
1315+
{datatype, string}
1316+
]}.
1317+
{translation, "rabbit.log.journald.fields",
1318+
fun(Conf) ->
1319+
rabbit_prelaunch_early_logging:translate_journald_fields_conf("log.journald.fields", Conf)
1320+
end}.
1321+
13071322
{mapping, "log.syslog", "rabbit.log.syslog.enabled", [
13081323
{datatype, {enum, [true, false]}}
13091324
]}.

0 commit comments

Comments
 (0)