When we fail to parse name of cipher suite from PROXY protocol
just say that no ssl is used, instead of trying to fill that
with data from connection between proxy and our server.
A user could already enable single-line logging (the `single_line`
option of `logger_formatter` or RabbitMQ internal formatters) from the
configuration file. For example:
log.console.formatter.single_line = on
With this patch, the option can be enabled from the `$RABBITMQ_LOG`
environment variable as well:
make run-broker RABBITMQ_LOG=+single_line
Those environment variables are unset by default. The default values are
set in the `rabbit` application environment and can be configured in the
configuration file. However, the environment variables will take
precedence over them respectively if they are set.
Unlike pg2, pg in Erlang 24 is eventually consistent. So this
reintroduces some of the same kind of locking mirrored_supervisor
used to rely on implicitly via pg2.
Per discussion with @lhoguin.
Closes#3260.
References #3132, #3154.
and assume it is a string-like value ("directory string")
because other values would not make much sense in the
username extraction context.
References #2983.
instead of specific ones since they will vary with the payload
(one of them likely indicates UTF string length).
This is still not perfect because we limit the maximum
allowed length but it works fine with identifiers up to 100
characters long, which should be good enough for this
best effort handling of an abscure SAN type.
References ##2983.
The parser didn't handle literals of the form:
'single-quoted'unquoted'single-quoted-again'"or-even-double-quoted"
In particular, the unquoted parsing assumed that nothing else could
follow it. The testsuite is extended with the issue reporter's case.
While here, improve escaped characters handling. They used to be not
parsed specifically at all.
Fixes#2969.
Note that the type by definition contains arbitrary values. According
to the OTP types, they are triplets that represent effectively
a key/value pair. So we assume the pair is a string that needs a bit
massaging, namely stripping the UTF encoding prefix OTP AnotherName
decoder leaves in.
Kudos to @Thibi2000 for providing an example value.
Closes#2983.
for usability. It is not any different from when a float value
is used and only exists as a counterpart to '{absolute, N}'.
Also nothing changes for rabbitmq.conf users as that format performs
validation and correct value translation.
See #2694, #2965 for background.
Adds WORKSPACE.bazel, BUILD.bazel & *.bzl files for partial build & test with Bazel. Introduces a build-time dependency on https://github.com/rabbitmq/bazel-erlang
In kind version 0.10.0, when creating a 5-node RabbitMQ cluster
with the new parallel PodManagementPolicy, we observed that some
pods were restarted. Their logs included:
```
10:10:03.794 [error]
10:10:03.804 [error] BOOT FAILED
10:10:03.805 [error] ===========
BOOT FAILED
10:10:03.805 [error] ERROR: epmd error for host r1-server-0.r1-nodes.rabbitmq-system: nxdomain (non-existing domain)
10:10:03.805 [error]
===========
ERROR: epmd error for host r1-server-0.r1-nodes.rabbitmq-system: nxdomain (non-existing domain)
10:10:04.806 [error] Supervisor rabbit_prelaunch_sup had child prelaunch started with rabbit_prelaunch:run_prelaunch_first_phase() at undefined exit with reason {epmd_error,"r1-server-0.r1-nodes.rabbitmq-system",nxdomain} in context start_error
10:10:04.806 [error] CRASH REPORT Process <0.152.0> with 0 neighbours exited with reason: {{shutdown,{failed_to_start_child,prelaunch,{epmd_error,"r1-server-0.r1-nodes.rabbitmq-system",nxdomain}}},{rabbit_prelaunch_app,start,[normal,[]]}} in application_master:init/4 line 138
```
Eventually, after some pods restarted up to 2 times, all pods were running and ready.
In kind, we observed that during the first couple of seconds, nslookup was failing as well for that domain
with nxdomain.
It took up to 30 seconds until nslookup succeeded.
With this commit, pods don't need to be restarted when creating a fresh
RabbitMQ cluster.
Lager strips trailing newline characters but OTP logger with the default
formatter adds a newline at the end. To avoid unintentional multi-line log
messages we have to revisit most messages logged.
Some log entries are intentionally multiline, others
are printed to stdout directly: newlines are required there
for sensible formatting.
The configuration remains the same for the end-user. The only exception
is the log root directory: it is now set through the `log_root`
application env. variable in `rabbit`. People using the Cuttlefish-based
configuration file are not affected by this exception.
The main change is how the logging facility is configured. It now
happens in `rabbit_prelaunch_logging`. The `rabbit_lager` module is
removed.
The supported outputs remain the same: the console, text files, the
`amq.rabbitmq.log` exchange and syslog.
The message text format slightly changed: the timestamp is more precise
(now to the microsecond) and the level can be abbreviated to always be
4-character long to align all messages and improve readability. Here is
an example:
2021-03-03 10:22:30.377392+01:00 [dbug] <0.229.0> == Prelaunch DONE ==
2021-03-03 10:22:30.377860+01:00 [info] <0.229.0>
2021-03-03 10:22:30.377860+01:00 [info] <0.229.0> Starting RabbitMQ 3.8.10+115.g071f3fb on Erlang 23.2.5
2021-03-03 10:22:30.377860+01:00 [info] <0.229.0> Licensed under the MPL 2.0. Website: https://rabbitmq.com
The example above also shows that multiline messages are supported and
each line is prepended with the same prefix (the timestamp, the level
and the Erlang process PID).
JSON is also supported as a message format and now for any outputs.
Indeed, it is possible to use it with e.g. syslog or the exchange. Here
is an example of a JSON-formatted message sent to syslog:
Mar 3 11:23:06 localhost rabbitmq-server[27908] <0.229.0> - {"time":"2021-03-03T11:23:06.998466+01:00","level":"notice","msg":"Logging: configured log handlers are now ACTIVE","meta":{"domain":"rabbitmq.prelaunch","file":"src/rabbit_prelaunch_logging.erl","gl":"<0.228.0>","line":311,"mfa":["rabbit_prelaunch_logging","configure_logger",1],"pid":"<0.229.0>"}}
For quick testing, the values accepted by the `$RABBITMQ_LOGS`
environment variables were extended:
* `-` still means stdout
* `-stderr` means stderr
* `syslog:` means syslog on localhost
* `exchange:` means logging to `amq.rabbitmq.log`
`$RABBITMQ_LOG` was also extended. It now accepts a `+json` modifier (in
addition to the existing `+color` one). With that modifier, messages are
formatted as JSON intead of plain text.
The `rabbitmqctl rotate_logs` command is deprecated. The reason is
Logger does not expose a function to force log rotation. However, it
will detect when a file was rotated by an external tool.
From a developer point of view, the old `rabbit_log*` API remains
supported, though it is now deprecated. It is implemented as regular
modules: there is no `parse_transform` involved anymore.
In the code, it is recommended to use the new Logger macros. For
instance, `?LOG_INFO(Format, Args)`. If possible, messages should be
augmented with some metadata. For instance (note the map after the
message):
?LOG_NOTICE("Logging: switching to configured handler(s); following "
"messages may not be visible in this log output",
#{domain => ?RMQLOG_DOMAIN_PRELAUNCH}),
Domains in Erlang Logger parlance are the way to categorize messages.
Some predefined domains, matching previous categories, are currently
defined in `rabbit_common/include/logging.hrl` or headers in the
relevant plugins for plugin-specific categories.
At this point, very few messages have been converted from the old
`rabbit_log*` API to the new macros. It can be done gradually when
working on a particular module or logging.
The Erlang builtin console/file handler, `logger_std_h`, has been forked
because it lacks date-based file rotation. The configuration of
date-based rotation is identical to Lager. Once the dust has settled for
this feature, the goal is to submit it upstream for inclusion in Erlang.
The forked module is calld `rabbit_logger_std_h` and is based
`logger_std_h` in Erlang 23.0.
as node names grow.
Prior to this change, direct reply-to consumer channels
were encoded using term_to_binary/1, which means the result
would grow together with node name (since node name
is one of the components of an Erlang pid type).
This means that with long enough hostnames, reply-to
identifiers could overflow the 255 character limit of
message property field type, longstr.
With this change, the encoded value uses a hash of the node name
and then locates the actual node name from a map of
hashes to current cluster members.
In addition, instead of generating non-predictable "secure"
GUIDs the feature now generates "regular" predictable GUIDs
which compensates some of the additional PID pre- and post-processing
outlined above.
The `set` command in the implementation of `/bin/sh` included in the
official RabbitMQ Docker image returns multi-line variable values
differently than the tested Bourne shell implementation (GNU Bash, dash
and FreeBSD sh).
I don't know what implementation is used by that Docker image, but here
is the output of `set`, for a variable set to "\n'test'":
TEST_VAR='
'"'"'test'"'"
The problem was reported in the following discussion:
https://github.com/rabbitmq/rabbitmq-server/discussions/2458
While here, add a small testcase to check a couple outputs.
GC collection can then be done by deleting all entries on the ETS table
and total counters per protocol can be kept without individually scanning
all entries
net_adm:name/1 returns a new value, 'noport', in Erlang 24. This value
being absent in the function spec in previous versions of Erlang, we get
a warning from Dialyzer until we start to the yet-to-be-release Erlang
24 in CI. Therefore we disable this specific warning.
On Windows, the current working directory is also searched, which can
lead to problems. Instead, use `init:get_argument(root)` to get the root
of the Erlang release, then we know `bin/erl` will always be present.
net_adm:name/1 returns a new value, 'noport', in Erlang 24. This value
being absent in the function spec in previous versions of Erlang, we get
a warning from Dialyzer until we start to the yet-to-be-release Erlang
24 in CI. Therefore we disable this specific warning.
On Windows, the current working directory is also searched, which can
lead to problems. Instead, use `init:get_argument(root)` to get the root
of the Erlang release, then we know `bin/erl` will always be present.
When we source the $CONF_ENV_FILE script, we set a few variables which
this script expects. Those variables are given without their prefix. For
instance, $MNESIA_BASE.
The $CONF_ENV_FILE script can set $RABBITMQ_MNESIA_BASE. Unfortunately
before this patch, the variable would be ignored, in favor of the
default value which was passed to the script ($MNESIA_BASE).
The reason is that variables set by the script are handled in the
alphabetical order. Thus $MNESIA_BASE is handled first, then
$RABBITMQ_MNESIA_BASE.
Because the code didn't give any precedence, the first variable set
would "win". This explains why users who set $RABBITMQ_MNESIA_BASE in
$CONF_ENV_FILE, but using RabbitMQ 3.8.4+ (which introduced
`rabbit_env`), unexpectedly had their node use the default Mnesia base
directory.
The patch is rather simple: when we check if a variable is already set,
we give precedence to the $RABBITMQ_* prefixed variables. Therefore, if
the $CONF_ENV_FILE script sets $RABBITMQ_MNESIA_BASE, this value will be
used, regardless of the value of $MNESIA_BASE.
This didn't happen with variables set in the environment (i.e. the
environment of rabbitmq-server(8)) because the prefixed variables
already had precedence.
Fixesrabbitmq/rabbitmq-common#401.
This allows RabbitMQ to configure `rabbit_log` as a Logger handler.
See a related commit in rabbit_prelaunch_early_logging in
rabbitmq-server, where `rabbit_log` is being configured as a Logger
handler. The commit message explains the reason behind this.
... and their value.
Both prefixed and non-prefixed variables are returned by this function.
While here, fix a conflict between $RABBITMQ_HOME and $HOME in
var_is_used/1: the latter shouldn't be considered as used.
dispatch_sync sits inbetween the behavior of submit and submit_async,
blocking the caller until a worker begins the task, as opposed
to not blocking at all, or blocking util the task has finished.
This is useful when you want to throttle submissions to the pool
from a single process, such that all workers are busy, but there
exists no backlog of work for the pool.
The previous value accepted for this behavior was "NONE". But it's more
intuitive to set it to nothing.
`rabbitmq-run.mk` is also updated to allow `$RABBITMQ_ENABLED_PLUGINS`
to be overriden e.g. on the command line.
It guesses the node name type, based on the host part of a node name.
I.e., if it contains at least a `.` character, it's a longname.
This matches the verification `net_kernel` does to make sure the node
name corresponds to the shortnames/longnames option.
There are two changes in this patch:
1. In `get_default_plugins_path_from_node(), we base the search on
`rabbit_common.app` instead of `code:lib_dir(rabbit_common)`.
The latter only works if the application directory is named
`rabbit_common` or `rabbit_common-$version`. This is not the case
with a default Git clone of the repository because the directory will
be named `rabbitmq-common`.
Using `rabbit_common.app` is fine because it is inside the `ebin`
directory, as all modules. It also brings another benefit: it is not
subject to cover-compilation or preloading (which both get rid of the
original module location).
2. The code to determine the plugins directory based on the directory
containing the module (or `rabbit_common.app`) now takes into account
plugin directories (as opposed to .ez archives). In this case, there
is one less path component compared to an .ez archive.
I.e. we record the fact that a particular value:
* is the default value, or
* comes from an environment variable, or
* comes from querying a remote node
This required a significant refactoring of the module, which explains
the large diff.
At the same time, the testsuite was extended to cover more code and
situations.
This work permits us to move remaining environment variables checked by
`rabbit` to this module. They include:
* $RABBITMQ_LOG_FF_REGISTRY
* $RABBITMQ_FEATURE_FLAGS
* $NOTIFY_SOCKET
[#170149339]
Compared to `all_module_attributes/0`, it only scans applications which
are related to RabbitMQ: either a RabbitMQ core application or a plugin
(i.e. an application which depends on `rabbit`).
On my laptop, this significantly reduce the time to query module
attributes in the case of feature flags: it goes from 830 ms to 235 ms
just by skipping all Erlang/OTP applications are third-party
dependencies.
This makes a small improvement to RabbitMQ startup time, which is
visible for developers mainly, not for a production instance.
There was one legitimate warning in `get_enabled_plugins()`:
`get_prefixed_env_var()` already takes care of converting an empty
string to false.
The other warning is because `loading_conf_env_file_enabled()` returns a
boolean when compiled for tests, but always true when compiled for
production. Dialyzer only sees the second case and thinks the cases
where the function returns false will never happen.
... and default values.
It can also query a remote node for some specific values. The use case
is the CLI which should know what the RabbitMQ node it controls uses
exactly.
It supports several new environment variables:
RABBITMQ_DBG:
Used to setup `dbg` for some simple tracing scenarios.
RABBITMQ_ENABLED_PLUGINS:
Used to list plugins to enable automatically on node startup.
RABBITMQ_KEEP_PID_FILE_ON_EXIT:
Used to indicate if the PID file should be removed or kept when the
node exits.
RABBITMQ_LOG:
Used to configure the global and per-category log levels and enable
ANSI colors.
At least on the Windows Server 2019 AWS EC2 image, the `tasklist`
command is unavailable.
If that's the case, we fallback to using a PowerShell oneliner. It's not
the default, just in case PowerShell is unavailable.
into a list, as the function implies.
All current call sites use it to call functions that return lists.
However, rabbitmq/rabbitmq-cli#389 breaks this cycle.
* Use `noinput`
* Use `-s erlang halt` to skip small `eval` overhead
* Use `no_dot_erlang` boot file since we do not want user customizations to interfere
These should be taken into account into the limits, but always be granted.
Files must be reserved by the queues themselves using `set_reservation/0` or
`set_reservation/1`. This is an absolute reservation that increases or
decreases the number of files reserved to reach the given amount on every
call.
[#169063174]
Add metadata to virtual hosts
[#166298298]
rabbit_vhost: use record defaults
The vhost record moved to a versioned record in rabbitmq-server
Co-Authored-By: Michael Klishin <mklishin@pivotal.io>
WIP, the secret is hardcoded, which is obviously not secured. It is
enough though to see if modules/applications manipulating credentials
can use it to avoid those credentials to end up in logs when the state
of crashed processes is dumped.
[#167070941]
References rabbitmq/rabbitmq-erlang-client#123
In Erlang 22, the name is now `aes_256_cbc`.
The default cipher/hash/iterations are also set in rabbit's application
default environment. I'm going to remove those default values there
because the code already queries this module if they are missing from
the application environment.
This fixes a crash of the call to `crypto:cipher_info/1` later because
the ciphers list returned by `crypto:supports/0` contains more ciphers:
"old aliases" are added to that list and those aliases are unsupported
by `crypto:cipher_info/1`.
This reverts commit 7c9f170cee.
CLI tools cannot use this function as it logs errors.
`rabbit_resource_monitor_misc:parse_information_unit/1` is a better fit.
Erlang 22 will introduce TLS 1.3, but at the time of this commit, only
the server side is implemented. If the Erlang client requests TLS 1.3, the
server will accept but the client will either hang or crash.
So for now, just blacklist TLS 1.3 to avoid any issues, even on the
server side, just to be safe.
[#165214130]
The `creation` field might not fit into one byte which makes the
`PID_EXT` format unsuitable for this case.
The `NEW_PID_EXT` format is supported since Erlang 19.0, so it is safe
to always use it, no matter the value of `creation`, because RabbitMQ
3.7+ requires at least Erlang 19.3+.
References #313.
In OTP-22 the Creation field has been increased to be 32 bits.
For now we only need to handle it when using term_to_binary
and parsing the result manually.
To fix this, introduce a new helper, `ascii_color/2`, which takes a the
same flag (`UseColors`) as its second argument. If that flag is false,
it returns an empty string.
While here, move the `isatty()` function in this module.
In particular, we drop support for Erlang R13B and older in
`rabbit_cert_info`. This fixes an error reported by Dialyzer now that
the list of dependencies (`$(LOCAL_DEPS)`) is more correct.
... in version_minor_equivalent().
Note that we'll need a special case to exclude 3.7.x versions which
don't have the feature flags modules.
At the same time, we introduce the `strict_version_minor_equivalent()`
function which has the behavior the initial function had before. This is
used in the context of plugin compatibility checks: plugins can specify
a `broker_version_requirements` property and at this point, plugins
compatible with 3.7.x should not be considered as compatible with 3.8.x.
[#159298729]
See the corresponding commit in rabbitmq-server for all the
explanations.
Now, all accesses to the #amqqueue{} record are made through the
`amqqueue` module (available in rabbitmq-server). The new type name is
`amqqueue:amqqueue()`.
The `amqqueue.hrl` header also provides some macros to help with pattern
matching and guard expressions.
To help with this, code and modules were moved from rabbitmq-common to
rabbitmq-server.
[#159298729]
* Add single active consumer flag in consumer metrics
* Add function to update consumer metrics when a consumer is promoted
to single active consumer
[#163089472]
References rabbitmq/rabbitmq-management#649
Allow the backing queue implementation to inform the amqqueue process
how to proceed when a message duplicate is encountered.
* {true, drop} the message is a duplicate and should be ignored
* {true, reject} the message is a duplicate and the publisher should
receive a rejection
* false the message is not deemed a duplicate
* true kept for backward compatibility, equivalent to {true, drop}
Signed-off-by: Matteo Cafasso <noxdafox@gmail.com>
To check whether a value is in the queue or not. Handle both
non-priority and priority queue. Based on lists:member/2, does not take
into account the priority of the value in the queue to check equality.
References rabbitmq/rabbitmq-server#1743