aboutsummaryrefslogtreecommitdiffstats
path: root/lib/kernel/doc
diff options
context:
space:
mode:
Diffstat (limited to 'lib/kernel/doc')
-rw-r--r--lib/kernel/doc/src/Makefile1
-rw-r--r--lib/kernel/doc/src/erl_epmd.xml104
-rw-r--r--lib/kernel/doc/src/kernel_app.xml45
-rw-r--r--lib/kernel/doc/src/logger.xml409
-rw-r--r--lib/kernel/doc/src/logger_chapter.xml35
-rw-r--r--lib/kernel/doc/src/logger_filters.xml14
-rw-r--r--lib/kernel/doc/src/logger_formatter.xml290
-rw-r--r--lib/kernel/doc/src/ref_man.xml1
-rw-r--r--lib/kernel/doc/src/specs.xml1
9 files changed, 686 insertions, 214 deletions
diff --git a/lib/kernel/doc/src/Makefile b/lib/kernel/doc/src/Makefile
index 82869d7b15..29dc73a523 100644
--- a/lib/kernel/doc/src/Makefile
+++ b/lib/kernel/doc/src/Makefile
@@ -42,6 +42,7 @@ XML_REF3_FILES = application.xml \
disk_log.xml \
erl_boot_server.xml \
erl_ddll.xml \
+ erl_epmd.xml \
erl_prim_loader_stub.xml \
erlang_stub.xml \
error_handler.xml \
diff --git a/lib/kernel/doc/src/erl_epmd.xml b/lib/kernel/doc/src/erl_epmd.xml
new file mode 100644
index 0000000000..8b076cd2d7
--- /dev/null
+++ b/lib/kernel/doc/src/erl_epmd.xml
@@ -0,0 +1,104 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<!DOCTYPE erlref SYSTEM "erlref.dtd">
+
+<erlref>
+ <header>
+ <copyright>
+ <year>2018</year><year>2018</year>
+ <holder>Ericsson AB. All Rights Reserved.</holder>
+ </copyright>
+ <legalnotice>
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+
+ </legalnotice>
+
+ <title>erl_epmd</title>
+ <prepared>Timmo Verlaan</prepared>
+ <docno>1</docno>
+ <date>2018-02-19</date>
+ <rev>A</rev>
+ </header>
+ <module>erl_epmd</module>
+ <modulesummary>
+ Erlang interface towards epmd
+ </modulesummary>
+ <description>
+ <p>This module communicates with the EPMD daemon, see <seealso
+ marker="erts:epmd">epmd</seealso>. To implement your own epmd module please
+ see <seealso marker="erts:alt_disco">ERTS User's Guide: How to Implement an
+ Alternative Service Discovery for Erlang Distribution</seealso></p>
+ </description>
+
+ <funcs>
+ <func>
+ <name name="start_link" arity="0"/>
+ <fsummary>Callback for erl_distribution supervisor.</fsummary>
+ <desc>
+ <p>This function is invoked as this module is added as a child of the
+ <c>erl_distribution</c> supervisor.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name name="register_node" arity="2"/>
+ <name name="register_node" arity="3"/>
+ <fsummary>Registers the node with <c>epmd</c>.</fsummary>
+ <desc>
+ <p>Registers the node with <c>epmd</c> and tells epmd what port will be
+ used for the current node. It returns a creation number. This number is
+ incremented on each register to help with identifying if a node is
+ reconnecting to epmd.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name name="port_please" arity="2"/>
+ <name name="port_please" arity="3"/>
+ <fsummary>Returns the port number for a given node.</fsummary>
+ <desc>
+ <p>Requests the distribution port for the given node of an EPMD
+ instance. Together with the port it returns a distribution protocol
+ version which has been 5 since Erlang/OTP R6.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name name="address_please" arity="3"/>
+ <fsummary>Returns address and port.</fsummary>
+ <desc>
+ <p>Called by the distribution module. Resolves the <c>Host</c> to an IP
+ address.</p>
+ <p>Another epmd module may return port and distribution protocol version
+ as well.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name name="names" arity="1"/>
+ <fsummary>Names of Erlang nodes at a host.</fsummary>
+ <desc>
+ <p>Called by <seealso marker="net_adm"><c>net_adm:names/0</c></seealso>.
+ <c>Host</c> defaults to the localhost. Returns the names and associated
+ port numbers of the Erlang nodes that <c>epmd</c> registered at the
+ specified host. Returns <c>{error, address}</c> if <c>epmd</c> is not
+ operational.</p>
+ <p><em>Example:</em></p>
+ <pre>
+(arne@dunn)1> <input>erl_epmd:names(localhost).</input>
+{ok,[{"arne",40262}]}</pre>
+ </desc>
+ </func>
+ </funcs>
+
+</erlref>
+
diff --git a/lib/kernel/doc/src/kernel_app.xml b/lib/kernel/doc/src/kernel_app.xml
index 554d675383..7894600c21 100644
--- a/lib/kernel/doc/src/kernel_app.xml
+++ b/lib/kernel/doc/src/kernel_app.xml
@@ -122,21 +122,6 @@
application. For more information about configuration parameters,
see file <seealso marker="app"><c>app(4)</c></seealso>.</p>
<taglist>
- <tag><c>browser_cmd = string() | {M,F,A}</c></tag>
- <item>
- <p>When pressing the <em>Help</em> button in a tool such as Debugger,
- the help text (an HTML file <c>File</c>) is by default
- displayed in a Netscape browser, which is required to be
- operational. This parameter can be used to change the command for
- how to display the help text if another browser than Netscape
- is preferred, or if another platform than Unix or Windows is
- used.</p>
- <p>If set to a string <c>Command</c>, the command
- <c>"Command File"</c> is evaluated using
- <seealso marker="os#cmd/1"><c>os:cmd/1</c></seealso>.</p>
- <p>If set to a module-function-args tuple, <c>{M,F,A}</c>,
- the call <c>apply(M,F,[File|A])</c> is evaluated.</p>
- </item>
<tag><c>distributed = [Distrib]</c></tag>
<item>
<p>Specifies which applications that are distributed and on which
@@ -226,7 +211,7 @@
<p>This configuration parameter is used both for the global
logger level, and for the standard handler started by
the Kernel application (see <c>logger_dest</c> variable above).</p>
- <p>The default value is <c>info</c></p>
+ <p>The default value is <c>info</c>.</p>
</item>
<tag><marker id="disk_log_vars"/>
<c>logger_disk_log_type = halt | wrap</c></tag>
@@ -251,14 +236,14 @@ logger_disk_log_maxbytes = 1048576</code>
<item>
<p>If this parameter is set to true, then the logger handler
started by kernel will not log any progress-, crash-, or
- supervisor reports. If the SASL application is starated,
+ supervisor reports. If the SASL application is started,
these log events will be sent to a second handler instance
- named sasl_h, according to values of the SASL environment
- variables <c>sasl_error_logger</c>
+ named <c>sasl_h</c>, according to values of the SASL
+ environment variables <c>sasl_error_logger</c>
and <c>sasl_errlog_type</c>, see
<seealso marker="sasl:sasl_app#configuration">SASL(6)
</seealso></p>
- <p>The default value is <c>false</c></p>
+ <p>The default value is <c>false</c>.</p>
<p>See chapter <seealso marker="logger_chapter#compatibility">Backwards
compatibility with error_logger</seealso> for more
information about handling of the so called SASL reports.</p>
@@ -271,7 +256,7 @@ logger_disk_log_maxbytes = 1048576</code>
reports from <c>supervisor</c>
and <c>application_controller</c> shall be logged or
not.</p>
- <p>If <c>logger_sasl_compatible = false</c>,
+ <p>If <c>logger_sasl_compatible = true</c>,
then <c>logger_log_progress</c> is ignored.</p>
</item>
<tag><marker id="logger_format_depth"/>
@@ -280,14 +265,6 @@ logger_disk_log_maxbytes = 1048576</code>
<p>Can be used to limit the size of the
formatted output from the logger handlers.</p>
- <note><p>This configuration parameter was introduced in OTP 18.1
- and is experimental. Based on user feedback, it
- can be changed or improved in future releases, for example,
- to gain better control over how to limit the size of the
- formatted output. We have no plans to remove this
- new feature entirely, unless it turns out to be
- useless.</p></note>
-
<p><c>Depth</c> is a positive integer representing the maximum
depth to which terms are printed by the logger
handlers included in OTP. This
@@ -312,11 +289,11 @@ logger_disk_log_maxbytes = 1048576</code>
</item>
<tag><c>logger_max_size = integer() | unlimited</c></tag>
<item>
- <p>This parameter specifies the maximum size (bytes) each
- log event can have when printed by the standard logger
- handler. If the resulting string after formatting an event
- is bigger than this, it will be truncated before printed
- to the handler's destination.</p>
+ <p>This parameter specifies a hard maximum size limit (number
+ of characters) each log event can have when printed by the
+ default logger formatter. If the resulting string after
+ formatting an event is bigger than this, it will be
+ truncated before printed to the handler's destination.</p>
</item>
<tag><c>logger_utc = boolean()</c></tag>
<item>
diff --git a/lib/kernel/doc/src/logger.xml b/lib/kernel/doc/src/logger.xml
index 66e6e5c689..d901454e62 100644
--- a/lib/kernel/doc/src/logger.xml
+++ b/lib/kernel/doc/src/logger.xml
@@ -67,37 +67,86 @@
<datatype>
<name name="metadata"/>
<desc>
- <p>Metadata associated with the message to be logged.</p>
+ <p>Metadata for the log event.</p>
+ <p>Logger adds the following metadata to each log event:</p>
+ <list>
+ <item><c>pid => self()</c></item>
+ <item><c>gl => group_leader()</c></item>
+ <item><c>time => erlang:monotonic_time(microsecond)</c></item>
+ </list>
+ <p>When a log macro is used, Logger also inserts location
+ information:</p>
+ <list>
+ <item><c>mfa => {?MODULE,?FUNCTION_NAME,?FUNCTION_ARITY}</c></item>
+ <item><c>file => ?FILE</c></item>
+ <item><c>line => ?LINE</c></item>
+ </list>
+ <p>You can add custom metadata, either by specifying a map as
+ the last parameter to any of the log macros or the API
+ functions, or by setting process metadata
+ with <seealso marker="#set_process_metadata-1">
+ <c>set_process_metadata/1</c></seealso>
+ or <seealso marker="#update_process_metadata-1">
+ <c>update_process_metadata/1</c></seealso>.</p>
+ <p>Logger merges all the metadata maps before forwarding the
+ log event to the handlers. If the same keys occur, values
+ from the log call overwrites process metadata, which in turn
+ overwrites values set by Logger.</p>
</desc>
</datatype>
<datatype>
<name name="config"/>
<desc>
- <p></p>
+ <p>Configuration data for the logger part of Logger, or for a handler.</p>
+ <p>The following default values apply:</p>
+ <list>
+ <item><c>level => info</c></item>
+ <item><c>filter_default => log</c></item>
+ <item><c>filters => []</c></item>
+ <item><c>formatter => {logger_formatter,DefaultFormatterConfig</c>}</item>
+ </list>
+ <p>See the <seealso marker="logger_formatter#configuration">
+ <c>logger_formatter(3)</c></seealso> manual page for
+ information about the default configuration for this
+ formatter.</p>
</desc>
</datatype>
<datatype>
<name name="handler_id"/>
<desc>
- <p></p>
+ <p>A unique identifier for a handler instance.</p>
</desc>
</datatype>
<datatype>
<name name="filter_id"/>
<desc>
- <p></p>
+ <p>A unique identifier for a filter.</p>
</desc>
</datatype>
<datatype>
<name name="filter"/>
<desc>
- <p></p>
+ <p>A filter which can be installed for logger or for a handler.</p>
+ </desc>
+ </datatype>
+ <datatype>
+ <name name="filter_arg"/>
+ <desc>
+ <p>The second argument to the filter fun.</p>
</desc>
</datatype>
<datatype>
<name name="filter_return"/>
<desc>
- <p></p>
+ <p>The return value from the filter fun.</p>
+ </desc>
+ </datatype>
+ <datatype>
+ <name name="timestamp"/>
+ <desc>
+ <p>A timestamp produced
+ with <seealso marker="erts:erlang#monotonic_time-1">
+ <c>erlang:monotonic_time(microsecond)</c></seealso>.</p>
</desc>
</datatype>
</datatypes>
@@ -126,14 +175,10 @@
</list>
<p>All macros expand to a call to logger, where <c>Level</c> is
- taken from the macro name, and the following metadata is added,
- or merged with the given <c>Metadata</c>:</p>
-
- <code>
-#{mfa=>{?MODULE,?FUNCTION_NAME,?FUNCTION_ARITY},
- file=>?FILE,
- line=>?LINE}
- </code>
+ taken from the macro name, and location data is added. See the
+ description of
+ the <seealso marker="#type-metadata"><c>metadata()</c></seealso>
+ type for more information about the location data.</p>
<p>The call is wrapped in a case statement and will be evaluated
only if <c>Level</c> is equal to or below the configured log
@@ -267,7 +312,7 @@
<func>
<name name="i" arity="0"/>
- <fsummary>Get information about all logger configurations</fsummary>
+ <fsummary>Get all logger configurations</fsummary>
<desc>
<p>Same as <seealso marker="#i/1"><c>logger:i(term)</c></seealso></p>
</desc>
@@ -277,27 +322,30 @@
<name name="i" arity="1" clause_i="1"/>
<name name="i" arity="1" clause_i="2"/>
<name name="i" arity="1" clause_i="3"/>
- <fsummary>Get information about all logger configurations</fsummary>
+ <fsummary>Get all logger configurations</fsummary>
<desc>
- <p>The <c>logger:i/1</c> function can be used to get all
- current logger configuration. The way that the information
- is returned depends on the <c><anno>Action</anno></c></p>
+ <p>Display or return all current logger configuration.</p>
<taglist>
- <tag>string</tag>
- <item>Return the pretty printed current logger configuration
- as iodata.</item>
- <tag>term</tag>
- <item>Return the current logger configuration as a term. The
- format of this term may change inbetween releases. For a
- stable format use <seealso marker="#get_handler_config/1">
+ <tag><c><anno>Action</anno> = string</c></tag>
+ <item>
+ <p>Return the pretty printed current logger configuration
+ as iodata.</p>
+ </item>
+ <tag><c><anno>Action</anno> = term</c></tag>
+ <item>
+ <p>Return the current logger configuration as a term. The
+ format of this term may change inbetween releases. For a
+ stable format use <seealso marker="#get_handler_config/1">
<c>logger:get_handler_config/1</c></seealso>
- and <seealso marker="#get_logger_config/0">
+ and <seealso marker="#get_logger_config/0">
<c>logger:get_logger_config/0</c></seealso>.
- The same as calling <c>logger:i()</c>.</item>
- <tag>print</tag>
- <item>Pretty print all the current logger configuration to
- standard out. Example:
- <code><![CDATA[1> logger:i().
+ The same as calling <c>logger:i()</c>.</p>
+ </item>
+ <tag><c><anno>Action</anno> = print</c></tag>
+ <item>
+ <p>Pretty print all the current logger configuration to
+ standard out. Example:</p>
+ <code><![CDATA[1> logger:i(print).
Current logger configuration:
Level: info
FilterDefault: log
@@ -339,6 +387,39 @@ Current logger configuration:
<fsummary>Add a filter to the logger.</fsummary>
<desc>
<p>Add a filter to the logger.</p>
+ <p>The filter fun is called with the log event as the first
+ parameter, and the specified <c>filter_args()</c> as the
+ second parameter.</p>
+ <p>The return value of the fun specifies if a log event is to
+ be discarded or forwarded to the handlers:</p>
+ <taglist>
+ <tag><c>log()</c></tag>
+ <item>
+ <p>The filter <em>passed</em>. The next logger filter, if
+ any, is applied. If no more logger filters exist, the
+ log event is forwarded to the handler part of the
+ logger, where handler filters are applied.</p>
+ </item>
+ <tag><c>stop</c></tag>
+ <item>
+ <p>The filter <em>did not pass</em>, and the log event is
+ immediately discarded.</p>
+ </item>
+ <tag><c>ignore</c></tag>
+ <item>
+ <p>The filter has no knowledge of the log event. The next
+ logger filter, if any, is applied. If no more logger
+ filters exist, the value of the <c>filter_default</c>
+ configuration parameter for the logger specifies if the
+ log event shall be discarded or forwarded to the handler
+ part.</p>
+ </item>
+ </taglist>
+ <p>See section <seealso marker="logger_chapter#Filter">
+ Filter</seealso> in the User's Guide for more information
+ about filters.</p>
+ <p>Some built-in filters exist. These are defined
+ in <seealso marker="logger_filters"><c>logger_filters</c></seealso>.</p>
</desc>
</func>
@@ -347,6 +428,39 @@ Current logger configuration:
<fsummary>Add a filter to the specified handler.</fsummary>
<desc>
<p>Add a filter to the specified handler.</p>
+ <p>The filter fun is called with the log event as the first
+ parameter, and the specified <c>filter_args()</c> as the
+ second parameter.</p>
+ <p>The return value of the fun specifies if a log event is to
+ be discarded or forwarded to the handler callback:</p>
+ <taglist>
+ <tag><c>log()</c></tag>
+ <item>
+ <p>The filter <em>passed</em>. The next handler filter, if
+ any, is applied. If no more filters exist for this
+ handler, the log event is forwarded to the handler
+ callback.</p>
+ </item>
+ <tag><c>stop</c></tag>
+ <item>
+ <p>The filter <em>did not pass</em>, and the log event is
+ immediately discarded.</p>
+ </item>
+ <tag><c>ignore</c></tag>
+ <item>
+ <p>The filter has no knowledge of the log event. The next
+ handler filter, if any, is applied. If no more filters
+ exist for this handler, the value of
+ the <c>filter_default</c> configuration parameter for
+ the handler specifies if the log event shall be
+ discarded or forwarded to the handler callback.</p>
+ </item>
+ </taglist>
+ <p>See
+ section <seealso marker="logger_chapter#Filter">Filter</seealso>
+ in the User's Guide for more information about filters.</p>
+ <p>Some built-in filters exist. These are defined in
+ <seealso marker="logger_filters"><c>logger_filters</c></seealso>.</p>
</desc>
</func>
@@ -354,7 +468,8 @@ Current logger configuration:
<name name="remove_logger_filter" arity="1"/>
<fsummary>Remove a filter from the logger.</fsummary>
<desc>
- <p>Remove the filter with the specified identity from the logger.</p>
+ <p>Remove the filter identified
+ by <c><anno>FilterId</anno></c> from the logger.</p>
</desc>
</func>
@@ -362,7 +477,9 @@ Current logger configuration:
<name name="remove_handler_filter" arity="2"/>
<fsummary>Remove a filter from the specified handler.</fsummary>
<desc>
- <p>Remove the filter with the specified identity from the given handler.</p>
+ <p>Remove the filter identified
+ by <c><anno>FilterId</anno></c> from the handler identified
+ by <c><anno>HandlerId</anno></c>.</p>
</desc>
</func>
@@ -371,6 +488,9 @@ Current logger configuration:
<fsummary>Add a handler with the given configuration.</fsummary>
<desc>
<p>Add a handler with the given configuration.</p>
+ <p><c><anno>HandlerId</anno></c> is a unique identifier which
+ must be used in all subsequent calls reffering to this
+ handler.</p>
</desc>
</func>
@@ -378,7 +498,7 @@ Current logger configuration:
<name name="remove_handler" arity="1"/>
<fsummary>Remove the handler with the specified identity.</fsummary>
<desc>
- <p>Remove the handler with the specified identity.</p>
+ <p>Remove the handler identified by <c><anno>HandlerId</anno></c>.</p>
</desc>
</func>
@@ -386,10 +506,37 @@ Current logger configuration:
<name name="set_module_level" arity="2"/>
<fsummary>Set the log level for the specified module.</fsummary>
<desc>
- <p>Set the log level for the specified module.</p>
- <p>To change the logging level globally, use
- <seealso marker="#set_logger_config/2"><c>logger:set_logger_config(level, Level)</c></seealso>.
- </p>
+ <p>Set the log level for the
+ specified <c><anno>Module</anno></c>.</p>
+ <p>The log level for a module overrides the global log level
+ of the logger for log event originating from the module in
+ question. Notice, however, that it does not override the
+ level configuration for any handler.</p>
+ <p>For example: Assume that the global log level for the
+ logger is <c>info</c>, and there is one handler, <c>h1</c>,
+ with level <c>info</c> and one handler, <c>h2</c>, with
+ level <c>debug</c>.</p>
+ <p>With this configuration, no debug messages will be logged,
+ since they are all stopped by the global log level.</p>
+ <p>If the level for <c>mymodule</c> is set now set
+ to <c>debug</c>, then debug events from this module will be
+ logged by the handler <c>h2</c>, but not by
+ handler <c>h1</c>.</p>
+ <p>Debug events from other modules are still not logged.</p>
+ <p>To change the global log level for the logger, use
+ <seealso marker="#set_logger_config/2">
+ <c>logger:set_logger_config(level,Level)</c></seealso>.</p>
+ <p>To change the log level for a handler, use
+ <seealso marker="#set_handler_config/3">
+ <c>logger:set_handler_config(HandlerId,level,Level)</c></seealso>.</p>
+ <note>
+ <p>The originating module for a log event is only detected
+ if <c>mfa=>{Module,Function,Arity}</c> exists in the
+ metadata. When log macros are used, this association is
+ automatically added to all log events. If the logger API
+ is called directly, without using a macro, the logging
+ client must explicitly add this information.</p>
+ </note>
</desc>
</func>
@@ -404,21 +551,62 @@ Current logger configuration:
<func>
<name name="set_logger_config" arity="1"/>
+ <fsummary>Set configuration data for the logger.</fsummary>
+ <desc>
+ <p>Set configuration data for the logger. This overwrites the
+ current logger configuration.</p>
+ <p>To modify the existing configuration,
+ use <seealso marker="#set_logger_config-2"><c>set_logger_config/2</c>
+ </seealso>, or read the current configuration
+ with <seealso marker="#get_logger_config-0"><c>get_logger_config/0</c>
+ </seealso>, then merge in your added or updated
+ associations before writing it back.</p>
+ <p>If a key is removed compared to the current configuration,
+ the default value is used.</p>
+ </desc>
+ </func>
+
+ <func>
<name name="set_logger_config" arity="2"/>
<fsummary>Add or update configuration data for the logger.</fsummary>
<desc>
- <p>Add or update configuration data for the logger.</p>
+ <p>Add or update configuration data for the logger. If the
+ given <c><anno>Key</anno></c> already exists, its associated
+ value will be changed to <c><anno>Value</anno></c>. If it
+ doesn't exist, it will be added.</p>
</desc>
</func>
<func>
<name name="set_handler_config" arity="2"/>
+ <fsummary>Set configuration data for the specified handler.</fsummary>
+ <desc>
+ <p>Set configuration data for the specified handler. This
+ overwrites the current handler configuration.</p>
+ <p>To modify the existing configuration,
+ use <seealso marker="#set_handler_config-3"><c>set_handler_config/3</c>
+ </seealso>, or read the current configuration
+ with <seealso marker="#get_handler_config-1"><c>get_handler_config/1</c>
+ </seealso>, then merge in your added or updated
+ associations before writing it back.</p>
+ <p>If a key is removed compared to the current configuration,
+ and the key is know by Logger, the default value is used. If
+ it is a custom key, then it is up to the handler
+ implementation if the value is removed or a default value is
+ inserted.</p>
+ </desc>
+ </func>
+
+ <func>
<name name="set_handler_config" arity="3"/>
<fsummary>Add or update configuration data for the specified
handler.</fsummary>
<desc>
<p>Add or update configuration data for the specified
- handler.</p>
+ handler. If the given <c><anno>Key</anno></c> already
+ exists, its associated value will be changed
+ to <c><anno>Value</anno></c>. If it doesn't exist, it will
+ be added.</p>
</desc>
</func>
@@ -437,17 +625,37 @@ Current logger configuration:
<name name="set_process_metadata" arity="1"/>
<fsummary>Set metadata to use when logging from current process.</fsummary>
<desc>
- <p>Set metadata which <c>logger</c> automatically inserts it
- in all log events produced on the current
- process. Subsequent calls will overwrite previous data set
- by this function.</p>
- <p>When logging, location data produced by the log macros,
- and/or metadata given as argument to the log call (API
- function or macro), will be merged with the process
- metadata. If the same keys occur, values from the metadata
- argument to the log call will overwrite values in the
- process metadata, which in turn will overwrite values from
- the location data.</p>
+ <p>Set metadata which Logger shall automatically insert in
+ all log events produced on the current process.</p>
+ <p>Location data produced by the log macros, and/or metadata
+ given as argument to the log call (API function or macro),
+ are merged with the process metadata. If the same keys
+ occur, values from the metadata argument to the log call
+ overwrite values from the process metadata, which in turn
+ overwrite values from the location data.</p>
+ <p>Subsequent calls to this function overwrites previous data
+ set. To update existing data instead of overwriting it,
+ see <seealso marker="#update_process_metadata-1">
+ <c>update_process_metadata/1</c></seealso>.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name name="update_process_metadata" arity="1"/>
+ <fsummary>Set or update metadata to use when logging from
+ current process.</fsummary>
+ <desc>
+ <p>Set or update metadata to use when logging from current
+ process</p>
+ <p>If process metadata exists for the current process, this
+ function behaves as if it was implemented as follows:</p>
+ <code type="erl">
+logger:set_process_metadata(maps:merge(logger:get_process_metadata(),Meta))
+ </code>
+ <p>If no process metadata exists, the function behaves as
+ <seealso marker="#set_process_metadata-1">
+ <c>set_process_metadata/1</c>
+ </seealso>.</p>
</desc>
</func>
@@ -457,7 +665,9 @@ Current logger configuration:
<desc>
<p>Retrieve data set
with <seealso marker="#set_process_metadata-1">
- <c>set_process_metadata/1</c></seealso>.</p>
+ <c>set_process_metadata/1</c></seealso> or
+ <seealso marker="#update_process_metadata-1">
+ <c>update_process_metadata/1</c></seealso>.</p>
</desc>
</func>
@@ -467,12 +677,103 @@ Current logger configuration:
<desc>
<p>Delete data set
with <seealso marker="#set_process_metadata-1">
- <c>set_process_metadata/1</c></seealso>.</p>
+ <c>set_process_metadata/1</c></seealso> or
+ <seealso marker="#update_process_metadata-1">
+ <c>update_process_metadata/1</c></seealso>.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name name="format_report" arity="1"/>
+ <fsummary>Convert a log message on report form to {Format,Args}.</fsummary>
+ <desc>
+ <p>Convert a log message on report form to <c>{Format,Args}</c>.</p>
+ <p>This is the default report callback used
+ by <seealso marker="logger_formatter">
+ <c>logger_formatter</c></seealso> when no custom report
+ callback is found.</p>
+ <p>The function produces lines of <c>Key: Value</c> from
+ key-value lists. Strings are printed with <c>~ts</c> and
+ other terms with <c>~tp</c>.</p>
+ <p>If the <c><anno>Report</anno></c> is a map, it is
+ converted to a key-value list before formatting as such.</p>
</desc>
</func>
</funcs>
+ <section>
+ <title>Callback Functions</title>
+ <p>The following functions are to be exported from a handler
+ callback module.</p>
+ </section>
+
+ <funcs>
+ <func>
+ <name>Module:adding_handler(HandlerId,Config1) -> {ok,Config2} | {error,Reason}</name>
+ <fsummary>An instance of this handler is about to be added.</fsummary>
+ <type>
+ <v>HandlerId =
+ <seealso marker="#type-handler_id">handler_id()</seealso></v>
+ <v>Config1 = Config2 =
+ <seealso marker="#type-config">config()</seealso></v>
+ <v>Reason = term()</v>
+ </type>
+ <desc>
+ <p>This callback function is optional.</p>
+ <p>The function is called when an new handler is about to be
+ added, and the purpose is to verify the configuration and
+ initiate all resourced needed by the handler.</p>
+ <p>If everything succeeds, the callback function can add
+ possible default values or internal state values to the
+ configuration, and return the adjusted map
+ in <c>{ok,Config2}</c>.</p>
+ <p>If the configuration is faulty, or if the initiation fails,
+ the callback function must return <c>{error,Reason}</c>.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name>Module:removing_handler(HandlerId,Config) -> ok</name>
+ <fsummary>The given handler is about to be removed.</fsummary>
+ <type>
+ <v>HandlerId =
+ <seealso marker="#type-handler_id">handler_id()</seealso></v>
+ <v>Config =
+ <seealso marker="#type-config">config()</seealso></v>
+ </type>
+ <desc>
+ <p>This callback function is optional.</p>
+ <p>The function is called when a handler is about to be
+ removed, and the purpose is to release all resources used by
+ the handler. The return value is ignored by Logger.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name>Module:changing_config(HandlerId,Config1,Config2) -> {ok,Config3} | {error,Reason}</name>
+ <fsummary>The configuration for this handler is about to change.</fsummary>
+ <type>
+ <v>HandlerId =
+ <seealso marker="#type-handler_id">handler_id()</seealso></v>
+ <v>Config1 = Config2 = Config3 =
+ <seealso marker="#type-config">config()</seealso></v>
+ <v>Reason = term()</v>
+ </type>
+ <desc>
+ <p>This callback function is optional.</p>
+ <p>The function is called when the configuration for a handler
+ is about to change, and the purpose is to verify and act on
+ the new configuration.</p>
+ <p><c>Config1</c> is the existing configuration
+ and <c>Config2</c> is the new configuration.</p>
+ <p>If everything succeeds, the callback function must return a
+ possibly adjusted configuration in <c>{ok,Config3}</c>.</p>
+ <p>If the configuration is faulty, the callback function must
+ return <c>{error,Reason}</c>.</p>
+ </desc>
+ </func>
+ </funcs>
</erlref>
diff --git a/lib/kernel/doc/src/logger_chapter.xml b/lib/kernel/doc/src/logger_chapter.xml
index 88dcfbe8d9..519df2ba48 100644
--- a/lib/kernel/doc/src/logger_chapter.xml
+++ b/lib/kernel/doc/src/logger_chapter.xml
@@ -157,7 +157,7 @@
<p>A formatter is defined as a module exporting the following
function:</p>
- <code>format(Log,Extra) -> string()</code>
+ <code>format(Log,Extra) -> unicode:chardata()</code>
<p>The formatter plugin is called by each handler, and the
returned string can be printed to the handler's destination
@@ -322,19 +322,6 @@
return <c>ignore</c>.</p>
<p>Default is <c>log</c>.</p>
</item>
- <tag><c>depth = pos_integer() | unlimited</c></tag>
- <item>
- <p>Specifies if the depth of terms in the log events shall
- be limited by using control characters <c>~P</c>
- and <c>~W</c> instead of <c>~p</c> and <c>~w</c>,
- respectively. See
- <seealso marker="stdlib:io#format-1"><c>io:format</c></seealso>.</p>
- </item>
- <tag><c>max_size = pos_integer() | unlimited</c></tag>
- <item>
- <p>Specifies if the size of a log event shall be limited by
- truncating the formatted string.</p>
- </item>
<tag><c>formatter = {Module::module(),Extra::term()}</c></tag>
<item>
<p>See <seealso marker="#Formatter">Formatter</seealso> for more
@@ -347,10 +334,9 @@
<p>Note that <c>level</c> and <c>filters</c> are obeyed by
Logger itself before forwarding the log events to each
- handler, while <c>depth</c>, <c>max_size</c>
- and <c>formatter</c> are left to the handler
- implementation. All Logger's built-in handlers do apply these
- configuration parameters before printing.</p>
+ handler, while <c>formatter</c> is left to the handler
+ implementation. All Logger's built-in handlers will call the
+ given formatter before printing.</p>
</section>
</section>
@@ -488,8 +474,9 @@ error_logger:add_report_handler/1,2.
level => debug}
2> <input>logger:add_handler(debug_handler,logger_std_h,Config).</input>
ok</pre>
- <p>By default, the handler receives all events, so we need to add a filter
- to stop all non-debug events:</p>
+ <p>By default, the handler receives all events
+ (<c>filter_defalt=log</c>), so we need to add a filter to stop
+ all non-debug events:</p>
<pre>
3> <input>Fun = fun(#{level:=debug}=Log,_) -> Log; (_,_) -> stop end.</input>
#Fun&lt;erl_eval.12.98642416>
@@ -516,7 +503,7 @@ ok</pre>
<p>It may also implement the following callbacks:</p>
<code>
adding_handler(logger:handler_id(),logger:config()) -> {ok,logger:config()} | {error,term()}
-removing_handler(logger:handler_id()) -> ok
+removing_handler(logger:handler_id(),logger:config()) -> ok
changing_config(logger:handler_id(),logger:config(),logger:config()) -> {ok,logger:config()} | {error,term()}
</code>
<p>When logger:add_handler(Id,Module,Config) is called, logger
@@ -526,7 +513,7 @@ changing_config(logger:handler_id(),logger:config(),logger:config()) -> {ok,logg
events as calls to Module:log/2.</p>
<p>A handler can be removed by calling
logger:remove_handler(Id). logger will call
- Module:removing_handler(Id), and then remove the handler's
+ Module:removing_handler(Id,Config), and then remove the handler's
configuration from the configuration database.</p>
<p>When logger:set_handler_config is called, logger calls
Module:changing_config(Id,OldConfig,NewConfig). If this function
@@ -547,7 +534,7 @@ log(Log,#{formatter:={FModule,FConfig}) ->
this:</p>
<code>
-module(myhandler).
--export([adding_handler/2, removing_handler/1, log/2]).
+-export([adding_handler/2, removing_handler/2, log/2]).
-export([init/1, handle_call/3, handle_cast/2, terminate/2]).
adding_handler(Id,Config) ->
@@ -576,7 +563,7 @@ log(Log,#{myhandler_fd:=Fd,formatter:={FModule,FConfig}}) ->
single process.</p>
<code>
-module(myhandler).
--export([adding_handler/2, removing_handler/1, log/2]).
+-export([adding_handler/2, removing_handler/2, log/2]).
-export([init/1, handle_call/3, handle_cast/2, terminate/2]).
adding_handler(Id,Config) ->
diff --git a/lib/kernel/doc/src/logger_filters.xml b/lib/kernel/doc/src/logger_filters.xml
index d742391e35..c34ec7d14c 100644
--- a/lib/kernel/doc/src/logger_filters.xml
+++ b/lib/kernel/doc/src/logger_filters.xml
@@ -33,16 +33,20 @@
<file>logger_filters.xml</file>
</header>
<module>logger_filters</module>
- <modulesummary>Filters to use with logger.</modulesummary>
+ <modulesummary>Filters to use with Logger.</modulesummary>
<description>
- <p>Filters to use with logger. All functions exported from this
- module can be used as logger or handler
+ <p>All functions exported from this module can be used as logger
+ or handler
filters. See <seealso marker="logger#add_logger_filter-2">
<c>logger:add_logger_filter/2</c></seealso>
and <seealso marker="logger#add_handler_filter-3">
- <c>logger:add_handler_filter/3</c></seealso>
- for more information about how filters are added.</p>
+ <c>logger:add_handler_filter/3</c></seealso> for more information
+ about how filters are added.</p>
+ <p>Filters are removed with <seealso marker="logger#remove_logger_filter-1">
+ <c>logger:remove_logger_filter/1</c></seealso>
+ and <seealso marker="logger#remove_handler_filter-2">
+ <c>logger:remove_handler_filter/2</c></seealso>.</p>
</description>
<funcs>
diff --git a/lib/kernel/doc/src/logger_formatter.xml b/lib/kernel/doc/src/logger_formatter.xml
index 6a17e3641f..7df4c88f40 100644
--- a/lib/kernel/doc/src/logger_formatter.xml
+++ b/lib/kernel/doc/src/logger_formatter.xml
@@ -33,12 +33,187 @@
<file>logger_formatter.xml</file>
</header>
<module>logger_formatter</module>
- <modulesummary>Default formatter for the Logger application.</modulesummary>
+ <modulesummary>Default formatter for Logger.</modulesummary>
<description>
- <p>Default formatter for the Logger application.</p>
+ <p>Each log handler has a configured formatter specified as a
+ module and a configuration term. The purpose of the formatter is
+ to translate the log events to a final printable string
+ (<c>unicode:chardata()</c>) which can be written to the output
+ device of the handler.</p>
+ <p><c>logger_formatter</c> is the default formatter used by
+ Logger.</p>
</description>
+ <section>
+ <title>Configuration</title>
+ <p>The configuration term for <c>logger_formatter</c> is a map,
+ and the following keys can be set as configuration
+ parameters:</p>
+ <taglist>
+ <tag><c>chars_limit = pos_integer() | unlimited</c></tag>
+ <item>
+ <p>A positive integer representing the value of the option
+ with the same name to be used when calling
+ <seealso marker="stdlib:io_lib#format-3">io_lib:format/3</seealso>.
+ This value limits the total number of characters printed
+ for each log event. Notice that this is a soft limit. For a
+ hard truncation limit, see option <c>max_size</c>.</p>
+ <p>Default is <c>unlimited</c>.</p>
+ <note>
+ <p><c>chars_limit</c> has no effect on log messages on
+ string form. These are expected to be short, but can still
+ be truncated by the <c>max_size</c> parameter.</p>
+ </note>
+ </item>
+ <tag><c>depth = pos_integer() | unlimited</c></tag>
+ <item>
+ <p>A positive integer representing the maximum depth to
+ which terms shall be printed by this formatter. Format
+ strings passed to this formatter are rewritten. The format
+ controls ~p and ~w are replaced with ~P and ~W,
+ respectively, and the value is used as the depth
+ parameter. For details, see
+ <seealso marker="stdlib:io#format-2">io:format/2,3</seealso>
+ in STDLIB.</p>
+ <p>Default is <c>unlimited</c>.</p>
+ <note>
+ <p><c>depth</c> has no effect on log messages on string
+ form. These are expected to be short, but can still be
+ truncated by the <c>max_size</c> parameter.</p>
+ </note>
+ </item>
+ <tag><c>max_size = pos_integer() | unlimited</c></tag>
+ <item>
+ <p>A positive integer representing the absolute maximum size a
+ string returned from this formatter can have. If the
+ formatted string is longer, after possibly being limited
+ by <c>chars_limit</c> or <c>depth</c>, it is truncated.</p>
+ <p>Default is <c>unlimited</c>.</p>
+ </item>
+ <tag><c>single_line = boolean()</c></tag>
+ <item>
+ <p>If set to <c>true</c>, all newlines in the message are
+ replaced with <c>", "</c>, and whitespaces following
+ directly after newlines are removed. Note that newlines
+ added by the <c>template</c> parameter are not replaced.</p>
+ <p>Default is <c>true</c>.</p>
+ </item>
+ <tag><c>legacy_header = boolen()</c></tag>
+ <item>
+ <p>If set to <c>true</c> a header field is added to
+ logger_formatter's part of <c>Metadata</c>. The value of
+ this field is a string similar to the header created by the
+ old <c>error_logger</c> event handlers. It can be included
+ in the log event by adding the
+ tuple <c>{logger_formatter,header}</c> to the template. See
+ section <seealso marker="#default_templates">Default
+ Templates</seealso> for more information.</p>
+ <p>Default is <c>false</c>.</p>
+ </item>
+ <tag><c>report_cb = fun((</c><seealso marker="logger#type-report"><c>logger:report()</c></seealso><c>) -> {</c><seealso marker="stdlib:io#type-format"><c>io:format()</c></seealso><c>,[term()]})</c></tag>
+ <item>
+ <p>A report callback is used by the formatter to transform log
+ messages on report form to a format string and
+ arguments. The report callback can be specified in the
+ metadata for the log event. If no report callback exist in
+ metadata, <c>logger_formatter</c> will
+ use <seealso marker="logger#format_report-1">
+ <c>logger:format_report/1</c></seealso> as default
+ callback.</p>
+ <p>If this configuration parameter is set, it replaces both
+ the default report callback, and any report callback found
+ in metadata. That is, all reports are converted by this
+ configured function.</p>
+ <p>The value must be a function with arity 1,
+ returning <c>{Format,Args}</c>, and it will be called with a
+ report as only argument.</p>
+ </item>
+ <tag><c>template = </c><seealso marker="#type-template"><c>template()</c></seealso></tag>
+ <item>
+ <p>The template is a list of atoms, tuples and strings. The
+ atoms <c>level</c> or <c>msg</c>, are treated as
+ placeholders for the severity level and the log message,
+ repectively. Other atoms or tuples are interpreted as
+ placeholders for metadata, where atoms are expected to match
+ top level keys, and tuples represent paths to sub keys when
+ the metadata is a nested map. For example the
+ tuple <c>{key1,key2}</c> is replaced by the value of
+ the <c>key2</c> field in the nested map below. The
+ atom <c>key1</c> on its own is replaced by the complete
+ value of the <c>key1</c> field. The values are converted to
+ strings.</p>
+
+<code>
+#{key1=>#{key2=>my_value,
+ ...}
+ ...}</code>
+
+ <p>Strings in the template are printed literally.</p>
+ <p>The default template differs depending on the values
+ of <c>legacy_header</c>
+ and <c>single_line</c>. See <seealso marker="#default_templates">Default
+ Templates</seealso> for more information</p>
+ </item>
+ <tag><c>utc = boolean()</c></tag>
+ <item>
+ <p>If set to <c>true</c>, all dates are displayed in Universal
+ Coordinated Time.</p>
+ <p>Default is <c>false</c>.</p>
+ </item>
+ </taglist>
+ </section>
+
+ <section>
+ <marker id="default_templates"/>
+ <title>Default templates</title>
+
+ <p>The default value for the <c>template</c> configuration
+ parameter depends on the value of <c>single_line</c>
+ and <c>legacy_header</c> as follows.</p>
+
+ <p>The log event used in the examples is:</p>
+ <code>
+?LOG_ERROR("name: ~p~nexit_reason: ~p",[my_reg_name,"It crashed"])</code>
+
+ <taglist>
+ <tag><c>legacy_header=true</c></tag>
+ <item>
+ <p>Default template: <c>[{logger_formatter,header},"\n",msg,"\n"]</c></p>
+
+ <p>Example log entry:</p>
+ <code>
+=ERROR REPORT==== 29-Dec-2017::13:30:51.245123 ===
+name: my_reg_name
+exit_reason: "It crashed"</code>
+
+ <p>Notice that all eight levels might occur in the heading,
+ not only <c>ERROR</c>, <c>WARNING</c> or <c>INFO</c> as the
+ old <c>error_logger</c> produced. And microseconds are
+ added at the end of the timestamp.</p>
+ </item>
+
+ <tag><c>single_line=true</c></tag>
+ <item>
+ <p>Default template: <c>[time," ",level,": ",msg,"\n"]</c></p>
+
+ <p>Example log entry:</p>
+ <code>2017-12-29 13:31:49.640317 error: name: my_reg_name, exit_reason: "It crashed"</code>
+ </item>
+
+ <tag><c>legacy_header=false, single_line=false</c></tag>
+ <item>
+ <p>Default template: <c>[time," ",level,":\n",msg,"\n"]</c></p>
+
+ <p>Example log entry:</p>
+ <code>
+2017-12-29 13:32:25.191925 error:
+name: my_reg_name
+exit_reason: "It crashed"</code>
+ </item>
+ </taglist>
+ </section>
+
<datatypes>
<datatype>
<name name="template"/>
@@ -52,101 +227,22 @@
<name name="format" arity="2"/>
<fsummary>Formats the given message.</fsummary>
<desc>
- <p>Formats the given message.</p>
- <p>The template is a list of atoms, tuples and strings. Atoms
- can be <c>level</c> or <c>msg</c>, which are placeholders
- for the severity level and the log message,
- repectively. Tuples are interpreted as placeholders for
- metadata. Each element in the tuple must be an atom which
- matches a key in the nested metadata map, e.g. the
- tuple <c>{key1,key2}</c> will be replaced by the value of
- the key2 field in this nested map (the value vill be
- converted to a string):</p>
-
-<code>
-#{key1=>#{key2=>my_value,
- ...},
- ...}</code>
-
-
- <p> Strings are printed literally.</p>
-
- <p><c>depth</c> is a positive integer representing the maximum
- depth to which terms shall be printed by this
- formatter. Format strings passed to this formatter are
- rewritten. The format controls ~p and ~w are replaced with
- ~P and ~W, respectively, and the value is used as the depth
- parameter. For details, see
- <seealso marker="stdlib:io#format-2">io:format/2,3</seealso>
- in STDLIB.</p>
-
- <p><c>chars_limit</c> is a positive integer representing the
- value of the option with the same name to be used when calling
- <seealso marker="stdlib:io#format-3">io:format/3</seealso>. This
- value limits the total number of characters printed bu the
- formatter. Notes that this is a soft limit. For a hard
- truncation limit, see option <c>max_size</c>.</p>
-
- <p><c>max_size</c> is a positive integer representing the
- maximum size a string returned from this formatter can
- have. If the formatted string is longer, after possibly
- being limited by <c>depth</c> and/or <c>chars_limit</c>, it
- will be truncated.</p>
-
- <p><c>utc</c> is a boolean. If set to true, all dates are
- displayed in Universal Coordinated Time. Default
- is <c>false</c>.</p>
-
- <p><c>report_cb</c> must be a function with arity 1,
- returning <c>{Format,Args}</c>. This function will replace
- any <c>report_cb</c> found in metadata.</p>
-
- <p>If <c>single_line=true</c>, all newlines in the message are
- replaced with <c>", "</c>, and whitespaces following directly
- after newlines are removed. Note that newlines added by the
- formatter template are not replaced.</p>
-
- <p>If <c>legacy_header=true</c> a header field is added to
- logger_formatter's part of <c>Metadata</c>. The value of
- this field is a string similar to the header created by the
- old <c>error_logger</c> event handlers. It can be included
- in the log event by adding the
- tuple <c>{logger_formatter,header}</c> to the template.</p>
-
- <p>The default template when <c>legacy_header=true</c> is</p>
-
- <code>[{logger_formatter,header},"\n",msg,"\n"]</code>
-
- <p>which will cause log entries like this:</p>
-
- <code>=ERROR REPORT==== 29-Dec-2017::13:30:51.245123 ===
- process: &lt;0.74.0&gt;
- exit_reason: "Something went wrong"</code>
-
- <p>Note that all eight levels might occur here, not
- only <c>ERROR</c>, <c>WARNING</c> or <c>INFO</c>. And also
- that micro seconds are added at the end of the
- timestamp.</p>
-
- <p>The default template when <c>single_line=true</c> is</p>
-
- <code>[time," ",level,": ",msg,"\n"]</code>
-
- <p>which will cause log entries like this:</p>
-
- <code>2017-12-29 13:31:49.640317 error: process: &lt;0.74.0&gt;, exit_reason: "Something went wrong"</code>
-
- <p>The default template when both <c>legacy_header</c> and
- <c>single_line</c> are set to false is:</p>
-
- <code>[time," ",level,":\n",msg,"\n"]</code>
-
- <p>which will cause log entries like this:</p>
-
- <code>2017-12-29 13:32:25.191925 error:
- process: &lt;0.74.0&gt;
- exit_reason: "Something went wrong"</code>
-
+ <p>This the formatter callback function to be called from
+ handlers. The log event is processed as follows:</p>
+ <list>
+ <item>If the message is on report form, it is converted to
+ <c>{Format,Args}</c> by calling the report
+ callback.</item>
+ <item>The size is limited according to the values of
+ configuration parameters <c>chars_limit</c>
+ and <c>depth</c>. Notice that this does not apply to
+ messages on string form.</item>
+ <item>The full log entry is composed according to
+ the <c>template</c>.</item>
+ <item>If the final string is too long, it is truncated
+ according to the value of configuration
+ parameter <c>max_size</c>.</item>
+ </list>
</desc>
</func>
diff --git a/lib/kernel/doc/src/ref_man.xml b/lib/kernel/doc/src/ref_man.xml
index c06914d23d..a633ae4832 100644
--- a/lib/kernel/doc/src/ref_man.xml
+++ b/lib/kernel/doc/src/ref_man.xml
@@ -38,6 +38,7 @@
<xi:include href="disk_log.xml"/>
<xi:include href="erl_boot_server.xml"/>
<xi:include href="erl_ddll.xml"/>
+ <xi:include href="erl_epmd.xml"/>
<xi:include href="erl_prim_loader_stub.xml"/>
<xi:include href="erlang_stub.xml"/>
<xi:include href="error_handler.xml"/>
diff --git a/lib/kernel/doc/src/specs.xml b/lib/kernel/doc/src/specs.xml
index bcc422930e..b8c25ca53b 100644
--- a/lib/kernel/doc/src/specs.xml
+++ b/lib/kernel/doc/src/specs.xml
@@ -6,6 +6,7 @@
<xi:include href="../specs/specs_disk_log.xml"/>
<xi:include href="../specs/specs_erl_boot_server.xml"/>
<xi:include href="../specs/specs_erl_ddll.xml"/>
+ <xi:include href="../specs/specs_erl_epmd.xml"/>
<xi:include href="../specs/specs_erl_prim_loader_stub.xml"/>
<xi:include href="../specs/specs_erlang_stub.xml"/>
<xi:include href="../specs/specs_error_handler.xml"/>