File 6865-kernel-Add-logger_handler-callbacks.patch of Package erlang
From 2afd6748f16ad226d0ae12b54e57e0147dafdbdd Mon Sep 17 00:00:00 2001
From: Lukas Larsson <lukas@erlang.org>
Date: Wed, 4 Oct 2023 13:59:22 +0200
Subject: [PATCH 05/10] kernel: Add logger_handler callbacks
We move the handler callbacks to a separate module so
that the documentation can live there and so that we
can use -behavior(logger_handler) which makes more sense
than -behaviour(logger).
---
lib/kernel/doc/src/Makefile | 1 +
lib/kernel/doc/src/logger.xml | 185 ++----------------
lib/kernel/doc/src/logger_chapter.xml | 16 +-
lib/kernel/doc/src/logger_handler.xml | 224 ++++++++++++++++++++++
lib/kernel/doc/src/ref_man.xml | 1 +
lib/kernel/doc/src/specs.xml | 1 +
lib/kernel/src/Makefile | 8 +-
lib/kernel/src/error_logger.erl | 8 +-
lib/kernel/src/kernel.app.src | 1 +
lib/kernel/src/logger.erl | 93 ++++-----
lib/kernel/src/logger_disk_log_h.erl | 4 +-
lib/kernel/src/logger_h_common.erl | 4 +-
lib/kernel/src/logger_handler.erl | 61 ++++++
lib/kernel/src/logger_handler_watcher.erl | 2 +-
lib/kernel/src/logger_simple_h.erl | 2 +
lib/kernel/src/logger_std_h.erl | 16 +-
16 files changed, 369 insertions(+), 258 deletions(-)
create mode 100644 lib/kernel/doc/src/logger_handler.xml
create mode 100644 lib/kernel/src/logger_handler.erl
diff --git a/lib/kernel/doc/src/Makefile b/lib/kernel/doc/src/Makefile
index a9fd26904a..143a841f3b 100644
--- a/lib/kernel/doc/src/Makefile
+++ b/lib/kernel/doc/src/Makefile
@@ -59,6 +59,7 @@ XML_REF3_FILES = application.xml \
logger_disk_log_h.xml \
logger_filters.xml \
logger_formatter.xml \
+ logger_handler.xml \
net.xml \
net_adm.xml \
net_kernel.xml \
diff --git a/lib/kernel/doc/src/logger.xml b/lib/kernel/doc/src/logger.xml
index 0c2a963e6e..ceafb8e0df 100644
--- a/lib/kernel/doc/src/logger.xml
+++ b/lib/kernel/doc/src/logger.xml
@@ -134,40 +134,21 @@ logger:error("error happened because: ~p", [Reason]). % Without macro
<datatype>
<name name="handler_config"/>
<desc>
- <p>Handler configuration data for Logger. The following
- default values apply:</p>
- <list>
- <item><c>level => all</c></item>
- <item><c>filter_default => log</c></item>
- <item><c>filters => []</c></item>
- <item><c>formatter => {logger_formatter, DefaultFormatterConfig</c>}</item>
- </list>
- <p>In addition to these, the following fields are
- automatically inserted by Logger, values taken from the
- two first parameters
- to <seemfa marker="#add_handler/3"><c>add_handler/3</c></seemfa>:</p>
- <list>
- <item><c>id => HandlerId</c></item>
- <item><c>module => Module</c></item>
- </list>
- <p>These are read-only and cannot be changed in runtime.</p>
- <p>Handler specific configuration data is inserted by the
- handler callback itself, in a sub structure associated with
- the field named <c>config</c>. See
- the <seeerl marker="logger_std_h"><c>logger_std_h(3)</c></seeerl>
- and <seeerl marker="logger_disk_log_h"><c>logger_disk_log_h(3)</c></seeerl>
- manual pages for information about the specific configuration
- for these handlers.</p>
- <p>See the <seetype marker="logger_formatter#config">
- <c>logger_formatter(3)</c></seetype> manual page for
- information about the default configuration for this
- formatter.</p>
+ <p>Handler configuration data for Logger.</p>
+ <note>
+ <p>DEPRECATED: Use <seetype marker="logger_handler#config"><c>logger_handler:config()</c></seetype> instead.
+ </p>
+ </note>
</desc>
</datatype>
<datatype>
<name name="handler_id"/>
<desc>
- <p>A unique identifier for a handler instance.</p>
+ <p>A unique identifier for a handler instance.</p>
+ <note>
+ <p>DEPRECATED: Use <seetype marker="logger_handler#id"><c>logger_handler:id()</c></seetype> instead.
+ </p>
+ </note>
</desc>
</datatype>
<datatype>
@@ -837,8 +818,8 @@ start(_, []) ->
the rest, use <seemfa marker="#update_handler_config/3">
<c>update_handler_config/3</c></seemfa>.</p>
<p>See the definition of
- the <seetype marker="#handler_config">
- <c>handler_config()</c></seetype> type for more
+ the <seetype marker="logger_handler#config">
+ <c>logger_handler:config()</c></seetype> type for more
information about the different parameters.</p>
</desc>
</func>
@@ -1073,8 +1054,8 @@ logger:set_handler_config(HandlerId, maps:merge(Old, Config)).
use <seemfa marker="#set_handler_config/3">
<c>set_handler_config/3</c></seemfa>.</p>
<p>See the definition of
- the <seetype marker="#handler_config">
- <c>handler_config()</c></seetype> type for more
+ the <seetype marker="logger_handler#config">
+ <c>logger_handler:config()</c></seetype> type for more
information about the different parameters.</p>
</desc>
</func>
@@ -1134,7 +1115,6 @@ logger:set_proxy_config(maps:merge(Old, Config)).
</func>
</funcs>
-
<funcs>
<fsdescription>
<marker id="misc_API"/>
@@ -1203,142 +1183,6 @@ logger:set_proxy_config(maps:merge(Old, Config)).
</funcs>
-
-
- <funcs>
- <fsdescription>
- <marker id="handler_callback_functions"/>
- <title>Handler Callback Functions</title>
- <p>The following functions are to be exported from a handler
- callback module.</p>
- </fsdescription>
- <func>
- <name since="OTP 21.0">Module:adding_handler(Config1) -> {ok, Config2} | {error,
- Reason}</name>
- <fsummary>An instance of this handler is about to be added.</fsummary>
- <type>
- <v>Config1 = Config2 =
- <seetype marker="#handler_config">handler_config()</seetype></v>
- <v>Reason = term()</v>
- </type>
- <desc>
- <p>This callback function is optional.</p>
- <p>The function is called on a temporary process when a new
- handler is about to be added. The purpose is to verify the
- configuration and initiate all resources needed by the
- handler.</p>
- <p>The handler identity is associated with the <c>id</c> key
- in <c>Config1</c>.</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 since="OTP 21.2">Module:changing_config(SetOrUpdate, OldConfig, NewConfig) -> {ok, Config} | {error, Reason}</name>
- <fsummary>The configuration for this handler is about to change.</fsummary>
- <type>
- <v>SetOrUpdate = set | update</v>
- <v>OldConfig = NewConfig = Config =
- <seetype marker="#handler_config">handler_config()</seetype></v>
- <v>Reason = term()</v>
- </type>
- <desc>
- <p>This callback function is optional.</p>
- <p>The function is called on a temporary process when the
- configuration for a handler is about to change. The purpose
- is to verify and act on the new configuration.</p>
- <p><c>OldConfig</c> is the existing configuration
- and <c>NewConfig</c> is the new configuration.</p>
- <p>The handler identity is associated with the <c>id</c> key
- in <c>OldConfig</c>.</p>
- <p><c>SetOrUpdate</c> has the value <c>set</c> if the
- configuration change originates from a call to
- <seemfa marker="#set_handler_config/2">
- <c>set_handler_config/2,3</c></seemfa>, and <c>update</c>
- if it originates from <seemfa marker="#update_handler_config/2">
- <c>update_handler_config/2,3</c></seemfa>. The handler can
- use this parameter to decide how to update the value of
- the <c>config</c> field, that is, the handler specific
- configuration data. Typically, if <c>SetOrUpdate</c>
- equals <c>set</c>, values that are not specified must be
- given their default values. If <c>SetOrUpdate</c>
- equals <c>update</c>, the values found in <c>OldConfig</c>
- must be used instead.</p>
- <p>If everything succeeds, the callback function must return a
- possibly adjusted configuration in <c>{ok,Config}</c>.</p>
- <p>If the configuration is faulty, the callback function must
- return <c>{error,Reason}</c>.</p>
- </desc>
- </func>
-
- <func>
- <name since="OTP 21.2">Module:filter_config(Config) -> FilteredConfig</name>
- <fsummary>Remove internal data from configuration.</fsummary>
- <type>
- <v>Config = FilteredConfig =
- <seetype marker="#handler_config">handler_config()</seetype></v>
- </type>
- <desc>
- <p>This callback function is optional.</p>
- <p>The function is called when one of the Logger API functions
- for fetching the handler configuration is called, for
- example
- <seemfa marker="#get_handler_config/1">
- <c>logger:get_handler_config/1</c></seemfa>.</p>
- <p>It allows the handler to remove internal data fields from
- its configuration data before it is returned to the
- caller.</p>
- </desc>
- </func>
-
- <func>
- <name since="OTP 21.0">Module:log(LogEvent, Config) -> void()</name>
- <fsummary>Log the given log event.</fsummary>
- <type>
- <v>LogEvent =
- <seetype marker="#log_event">log_event()</seetype></v>
- <v>Config =
- <seetype marker="#handler_config">handler_config()</seetype></v>
- </type>
- <desc>
- <p>This callback function is mandatory.</p>
- <p>The function is called when all primary filters and all
- handler filters for the handler in question have passed for
- the given log event. It is called on the client process, that
- is, the process that issued the log event.</p>
- <p>The handler identity is associated with the <c>id</c> key
- in <c>Config</c>.</p>
- <p>The handler must log the event.</p>
- <p>The return value from this function is ignored by
- Logger.</p>
- </desc>
- </func>
-
- <func>
- <name since="OTP 21.0">Module:removing_handler(Config) -> ok</name>
- <fsummary>The given handler is about to be removed.</fsummary>
- <type>
- <v>Config =
- <seetype marker="#handler_config">handler_config()</seetype></v>
- </type>
- <desc>
- <p>This callback function is optional.</p>
- <p>The function is called on a temporary process when a
- handler is about to be removed. The purpose is to release
- all resources used by the handler.</p>
- <p>The handler identity is associated with the <c>id</c> key
- in <c>Config</c>.</p>
- <p>The return value is ignored by Logger.</p>
- </desc>
- </func>
-
- </funcs>
-
<section>
<title>See Also</title>
<p>
@@ -1347,6 +1191,7 @@ logger:set_proxy_config(maps:merge(Old, Config)).
<seeerl marker="stdlib:io"><c>io(3)</c></seeerl>,
<seeerl marker="logger_disk_log_h"><c>logger_disk_log_h(3)</c></seeerl>,
<seeerl marker="logger_filters"><c>logger_filters(3)</c></seeerl>,
+ <seeerl marker="logger_handler"><c>logger_handler(3)</c></seeerl>,
<seeerl marker="logger_formatter"><c>logger_formatter(3)</c></seeerl>,
<seeerl marker="logger_std_h"><c>logger_std_h(3)</c></seeerl>,
<seeerl marker="stdlib:unicode"><c>unicode(3)</c></seeerl>
diff --git a/lib/kernel/doc/src/logger_chapter.xml b/lib/kernel/doc/src/logger_chapter.xml
index d35cef3465..302666cc3e 100644
--- a/lib/kernel/doc/src/logger_chapter.xml
+++ b/lib/kernel/doc/src/logger_chapter.xml
@@ -390,7 +390,7 @@ logger:debug(#{got => connection_request, id => Id, state => State},
<p>A handler is defined as a module exporting at least the
following callback function:</p>
- <pre><seemfa marker="logger#Module:log/2">log(LogEvent, Config) -> void()</seemfa></pre>
+ <pre><seemfa marker="logger_handler#Module:log/2">log(LogEvent, Config) -> void()</seemfa></pre>
<p>This function is called when a log event has passed through all
primary filters, and all handler filters attached to the handler
@@ -408,9 +408,8 @@ logger:debug(#{got => connection_request, id => Id, state => State},
handler module can export the optional callback
functions <c>adding_handler/1</c>, <c>changing_config/3</c>,
<c>filter_config/1</c>, and <c>removing_handler/1</c>. See
- section <seeerl marker="logger#handler_callback_functions">Handler
- Callback Functions</seeerl> in the logger(3) manual page for
- more information about these function.</p>
+ <seeerl marker="logger_handler">logger_handler(3)</seeerl>
+ for more information about these function.</p>
<p>The following built-in handlers exist:</p>
@@ -453,7 +452,7 @@ logger:debug(#{got => connection_request, id => Id, state => State},
handler's destination. The handler callback receives the
formatter information as part of the handler configuration,
which is passed as the second argument
- to <seemfa marker="logger#Module:log/2">
+ to <seemfa marker="logger_handler#Module:log/2">
<c>HModule:log/2</c></seemfa>.</p>
<p>The formatter information consist of a formatter
module, <c>FModule</c> and its
@@ -594,8 +593,8 @@ logger:debug(#{got => connection_request, id => Id, state => State},
</list>
<p>The configuration for a handler is a map with the following keys:</p>
<taglist>
- <tag><c>id = </c><seetype marker="logger#handler_id">
- <c>logger:handler_id()</c></seetype></tag>
+ <tag><c>id = </c><seetype marker="logger_handler#id">
+ <c>logger_handler:id()</c></seetype></tag>
<item>
<p>Automatically inserted by Logger. The value is the same
as the <c>HandlerId</c> specified when adding the handler,
@@ -1062,8 +1061,7 @@ ok</pre>
<section>
<title>Example: Implement a handler</title>
- <p>Section <seeerl marker="logger#handler_callback_functions">Handler
- Callback Functions</seeerl> in the logger(3) manual page
+ <p><seeerl marker="logger_handler">logger_handler(3)</seeerl>
describes the callback functions that can be implemented for a
Logger handler.</p>
<p>A handler callback module must export:</p>
diff --git a/lib/kernel/doc/src/logger_handler.xml b/lib/kernel/doc/src/logger_handler.xml
new file mode 100644
index 0000000000..204a2a2244
--- /dev/null
+++ b/lib/kernel/doc/src/logger_handler.xml
@@ -0,0 +1,224 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<!DOCTYPE erlref SYSTEM "erlref.dtd">
+
+<erlref>
+ <header>
+ <copyright>
+ <year>2023</year><year>2023</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>logger_handler</title>
+ <prepared></prepared>
+ <responsible></responsible>
+ <docno></docno>
+ <approved></approved>
+ <checked></checked>
+ <date></date>
+ <rev>A</rev>
+ <file>logger_handler.xml</file>
+ </header>
+ <module since="OTP @OTP-XYZ@">logger_handler</module>
+ <modulesummary>logger_handler behavior module.</modulesummary>
+
+ <description>
+ <p>The behaviour module for logger handlers. A logger handler
+ is a callback module that is called when a log event has passed
+ all filters and is ready to be logged somewhere. For more information
+ see <seeguide marker="logger_chapter#handlers">Handlers</seeguide> in
+ the Users Guide.</p>
+ </description>
+
+ <datatypes>
+ <datatype>
+ <name name="config"/>
+ <desc>
+ <p>Handler configuration data for Logger. The following
+ default values apply:</p>
+ <list>
+ <item><c>level => all</c></item>
+ <item><c>filter_default => log</c></item>
+ <item><c>filters => []</c></item>
+ <item><c>formatter => {logger_formatter, DefaultFormatterConfig</c>}</item>
+ </list>
+ <p>In addition to these, the following fields are
+ automatically inserted by Logger, values taken from the
+ two first parameters
+ to <seemfa marker="logger#add_handler/3"><c>logger:add_handler/3</c></seemfa>:</p>
+ <list>
+ <item><c>id => HandlerId</c></item>
+ <item><c>module => Module</c></item>
+ </list>
+ <p>These are read-only and cannot be changed in runtime.</p>
+ <p>Handler specific configuration data is inserted by the
+ handler callback itself, in a sub structure associated with
+ the field named <c>config</c>. See
+ the <seeerl marker="logger_std_h"><c>logger_std_h(3)</c></seeerl>
+ and <seeerl marker="logger_disk_log_h"><c>logger_disk_log_h(3)</c></seeerl>
+ manual pages for information about the specific configuration
+ for these handlers.</p>
+ <p>See the <seetype marker="logger_formatter#config">
+ <c>logger_formatter(3)</c></seetype> manual page for
+ information about the default configuration for this
+ formatter.</p>
+ </desc>
+ </datatype>
+ <datatype>
+ <name name="id"/>
+ <desc>
+ <p>A unique identifier for a handler instance.</p>
+ </desc>
+ </datatype>
+ </datatypes>
+
+ <funcs>
+ <func>
+ <name since="OTP 21.0">Module:adding_handler(Config1) -> {ok, Config2} | {error,
+ Reason}</name>
+ <fsummary>An instance of this handler is about to be added.</fsummary>
+ <type>
+ <v>Config1 = Config2 =
+ <seetype marker="#config">config()</seetype></v>
+ <v>Reason = term()</v>
+ </type>
+ <desc>
+ <p>This callback function is optional.</p>
+ <p>The function is called on a temporary process when a new
+ handler is about to be added. The purpose is to verify the
+ configuration and initiate all resources needed by the
+ handler.</p>
+ <p>The handler identity is associated with the <c>id</c> key
+ in <c>Config1</c>.</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 since="OTP 21.2">Module:changing_config(SetOrUpdate, OldConfig, NewConfig) -> {ok, Config} | {error, Reason}</name>
+ <fsummary>The configuration for this handler is about to change.</fsummary>
+ <type>
+ <v>SetOrUpdate = set | update</v>
+ <v>OldConfig = NewConfig = Config =
+ <seetype marker="#config">config()</seetype></v>
+ <v>Reason = term()</v>
+ </type>
+ <desc>
+ <p>This callback function is optional.</p>
+ <p>The function is called on a temporary process when the
+ configuration for a handler is about to change. The purpose
+ is to verify and act on the new configuration.</p>
+ <p><c>OldConfig</c> is the existing configuration
+ and <c>NewConfig</c> is the new configuration.</p>
+ <p>The handler identity is associated with the <c>id</c> key
+ in <c>OldConfig</c>.</p>
+ <p><c>SetOrUpdate</c> has the value <c>set</c> if the
+ configuration change originates from a call to
+ <seemfa marker="logger#set_handler_config/2">
+ <c>logger:set_handler_config/2,3</c></seemfa>, and <c>update</c>
+ if it originates from <seemfa marker="logger#update_handler_config/2">
+ <c>logger:update_handler_config/2,3</c></seemfa>. The handler can
+ use this parameter to decide how to update the value of
+ the <c>config</c> field, that is, the handler specific
+ configuration data. Typically, if <c>SetOrUpdate</c>
+ equals <c>set</c>, values that are not specified must be
+ given their default values. If <c>SetOrUpdate</c>
+ equals <c>update</c>, the values found in <c>OldConfig</c>
+ must be used instead.</p>
+ <p>If everything succeeds, the callback function must return a
+ possibly adjusted configuration in <c>{ok,Config}</c>.</p>
+ <p>If the configuration is faulty, the callback function must
+ return <c>{error,Reason}</c>.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name since="OTP 21.2">Module:filter_config(Config) -> FilteredConfig</name>
+ <fsummary>Remove internal data from configuration.</fsummary>
+ <type>
+ <v>Config = FilteredConfig =
+ <seetype marker="#config">config()</seetype></v>
+ </type>
+ <desc>
+ <p>This callback function is optional.</p>
+ <p>The function is called when one of the Logger API functions
+ for fetching the handler configuration is called, for
+ example
+ <seemfa marker="logger#get_handler_config/1">
+ <c>logger:get_handler_config/1</c></seemfa>.</p>
+ <p>It allows the handler to remove internal data fields from
+ its configuration data before it is returned to the
+ caller.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name since="OTP 21.0">Module:log(LogEvent, Config) -> void()</name>
+ <fsummary>Log the given log event.</fsummary>
+ <type>
+ <v>LogEvent =
+ <seetype marker="logger#log_event">logger:log_event()</seetype></v>
+ <v>Config =
+ <seetype marker="#config">config()</seetype></v>
+ </type>
+ <desc>
+ <p>This callback function is mandatory.</p>
+ <p>The function is called when all primary filters and all
+ handler filters for the handler in question have passed for
+ the given log event. It is called on the client process, that
+ is, the process that issued the log event.</p>
+ <p>The handler identity is associated with the <c>id</c> key
+ in <c>Config</c>.</p>
+ <p>The handler must log the event.</p>
+ <p>The return value from this function is ignored by
+ Logger.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name since="OTP 21.0">Module:removing_handler(Config) -> ok</name>
+ <fsummary>The given handler is about to be removed.</fsummary>
+ <type>
+ <v>Config =
+ <seetype marker="#config">config()</seetype></v>
+ </type>
+ <desc>
+ <p>This callback function is optional.</p>
+ <p>The function is called on a temporary process when a
+ handler is about to be removed. The purpose is to release
+ all resources used by the handler.</p>
+ <p>The handler identity is associated with the <c>id</c> key
+ in <c>Config</c>.</p>
+ <p>The return value is ignored by Logger.</p>
+ </desc>
+ </func>
+
+ </funcs>
+
+ <section>
+ <title>See Also</title>
+ <p>
+ <seeerl marker="logger_filters"><c>logger_filters(3)</c></seeerl>,
+ <seeerl marker="logger_formatter"><c>logger_formatter(3)</c></seeerl>,
+ <seeerl marker="logger"><c>logger(3)</c></seeerl>
+ </p>
+ </section>
+</erlref>
diff --git a/lib/kernel/doc/src/ref_man.xml b/lib/kernel/doc/src/ref_man.xml
index 39973158d6..05c022e4ea 100644
--- a/lib/kernel/doc/src/ref_man.xml
+++ b/lib/kernel/doc/src/ref_man.xml
@@ -59,6 +59,7 @@
<xi:include href="logger.xml"/>
<xi:include href="logger_filters.xml"/>
<xi:include href="logger_formatter.xml"/>
+ <xi:include href="logger_handler.xml"/>
<xi:include href="logger_std_h.xml"/>
<xi:include href="logger_disk_log_h.xml"/>
<xi:include href="net.xml"/>
diff --git a/lib/kernel/doc/src/specs.xml b/lib/kernel/doc/src/specs.xml
index fd3877d9a8..ec7f0af552 100644
--- a/lib/kernel/doc/src/specs.xml
+++ b/lib/kernel/doc/src/specs.xml
@@ -25,6 +25,7 @@
<xi:include href="../specs/specs_logger.xml"/>
<xi:include href="../specs/specs_logger_filters.xml"/>
<xi:include href="../specs/specs_logger_formatter.xml"/>
+ <xi:include href="../specs/specs_logger_handler.xml"/>
<xi:include href="../specs/specs_logger_std_h.xml"/>
<xi:include href="../specs/specs_logger_disk_log_h.xml"/>
<xi:include href="../specs/specs_net.xml"/>
diff --git a/lib/kernel/src/Makefile b/lib/kernel/src/Makefile
index 929f1d2c4e..8ac4768674 100644
--- a/lib/kernel/src/Makefile
+++ b/lib/kernel/src/Makefile
@@ -119,6 +119,7 @@ MODULES = \
logger \
logger_backend \
logger_config \
+ logger_handler \
logger_handler_watcher \
logger_std_h \
logger_disk_log_h \
@@ -185,6 +186,7 @@ APPUP_TARGET= $(EBIN)/$(APPUP_FILE)
ERL_COMPILE_FLAGS += -Werror
ERL_COMPILE_FLAGS += -I../include
+ERL_COMPILE_FLAGS += -pa ../ebin
# ----------------------------------------------------
@@ -283,14 +285,14 @@ $(EBIN)/local_tcp.beam: inet_int.hrl
$(EBIN)/logger.beam: logger_internal.hrl ../include/logger.hrl
$(EBIN)/logger_backend.beam: logger_internal.hrl ../include/logger.hrl
$(EBIN)/logger_config.beam: logger_internal.hrl ../include/logger.hrl
-$(EBIN)/logger_disk_log_h.beam: logger_h_common.hrl logger_internal.hrl ../include/logger.hrl ../include/file.hrl
+$(EBIN)/logger_disk_log_h.beam: $(EBIN)/logger_handler.beam logger_h_common.hrl logger_internal.hrl ../include/logger.hrl ../include/file.hrl
$(EBIN)/logger_filters.beam: logger_internal.hrl ../include/logger.hrl
$(EBIN)/logger_formatter.beam: logger_internal.hrl ../include/logger.hrl
$(EBIN)/logger_olp.beam: logger_olp.hrl logger_internal.hrl
$(EBIN)/logger_proxy.beam: logger_internal.hrl
$(EBIN)/logger_server.beam: logger_internal.hrl ../include/logger.hrl
-$(EBIN)/logger_simple_h.beam: logger_internal.hrl ../include/logger.hrl
-$(EBIN)/logger_std_h.beam: logger_h_common.hrl logger_internal.hrl ../include/logger.hrl ../include/file.hrl
+$(EBIN)/logger_simple_h.beam: $(EBIN)/logger_handler.beam logger_internal.hrl ../include/logger.hrl
+$(EBIN)/logger_std_h.beam: $(EBIN)/logger_handler.beam logger_h_common.hrl logger_internal.hrl ../include/logger.hrl ../include/file.hrl
$(EBIN)/logger_h_common.beam: logger_h_common.hrl logger_internal.hrl ../include/logger.hrl
$(EBIN)/net_kernel.beam: ../include/net_address.hrl
$(EBIN)/os.beam: ../include/file.hrl
diff --git a/lib/kernel/src/error_logger.erl b/lib/kernel/src/error_logger.erl
index 829f28f00d..c243fa9fd3 100644
--- a/lib/kernel/src/error_logger.erl
+++ b/lib/kernel/src/error_logger.erl
@@ -106,8 +106,8 @@ stop() ->
%%%-----------------------------------------------------------------
%%% Callbacks for logger
--spec adding_handler(logger:handler_config()) ->
- {ok,logger:handler_config()} | {error,term()}.
+-spec adding_handler(logger_handler:config()) ->
+ {ok,logger_handler:config()} | {error,term()}.
adding_handler(#{id:=?MODULE}=Config) ->
case start() of
ok ->
@@ -116,12 +116,12 @@ adding_handler(#{id:=?MODULE}=Config) ->
Error
end.
--spec removing_handler(logger:handler_config()) -> ok.
+-spec removing_handler(logger_handler:config()) -> ok.
removing_handler(#{id:=?MODULE}) ->
stop(),
ok.
--spec log(logger:log_event(),logger:handler_config()) -> ok.
+-spec log(logger:log_event(),logger_handler:config()) -> ok.
log(#{level:=Level,msg:=Msg,meta:=Meta},_Config) ->
do_log(Level,Msg,Meta).
diff --git a/lib/kernel/src/kernel.app.src b/lib/kernel/src/kernel.app.src
index 4ae0fb6bb5..a06840ac1c 100644
--- a/lib/kernel/src/kernel.app.src
+++ b/lib/kernel/src/kernel.app.src
@@ -72,6 +72,7 @@
logger_filters,
logger_formatter,
logger_h_common,
+ logger_handler,
logger_handler_watcher,
logger_olp,
logger_proxy,
diff --git a/lib/kernel/src/logger.erl b/lib/kernel/src/logger.erl
index 83f7aeba2a..14f47ddf9b 100644
--- a/lib/kernel/src/logger.erl
+++ b/lib/kernel/src/logger.erl
@@ -103,7 +103,6 @@
-type location() :: #{mfa := {module(),atom(),non_neg_integer()},
file := file:filename(),
line := non_neg_integer()}.
--type handler_id() :: atom().
-type filter_id() :: atom().
-type filter() :: {fun((log_event(),filter_arg()) ->
filter_return()),filter_arg()}.
@@ -113,17 +112,10 @@
metadata => metadata(),
filter_default => log | stop,
filters => [{filter_id(),filter()}]}.
--type handler_config() :: #{id => handler_id(),
- config => term(),
- level => level() | all | none,
- module => module(),
- filter_default => log | stop,
- filters => [{filter_id(),filter()}],
- formatter => {module(),formatter_config()}}.
-type timestamp() :: integer().
-type formatter_config() :: #{atom() => term()}.
--type config_handler() :: {handler, handler_id(), module(), handler_config()}.
+-type config_handler() :: {handler, logger_handler:id(), module(), logger_handler:config()}.
-type config_logger() :: [{handler,default,undefined} |
config_handler() |
@@ -142,6 +134,10 @@
overload_kill_restart_after =>
non_neg_integer() | infinity}.
+%% Kept for backwards compatibility
+-type handler_id() :: logger_handler:id().
+-type handler_config() :: logger_handler:config().
+
-export_type([log_event/0,
level/0,
report/0,
@@ -161,31 +157,6 @@
olp_config/0,
timestamp/0]).
-%%%-----------------------------------------------------------------
-%%% Callbacks
--callback adding_handler(Config1) -> {ok, Config2} | {error, Reason} when
- Config1 :: handler_config(),
- Config2 :: handler_config(),
- Reason :: term().
-
--callback changing_config(SetOrUpdate, OldConfig, NewConfig) ->
- {ok, Config} | {error, Reason} when
- SetOrUpdate :: set | update,
- OldConfig :: handler_config(),
- NewConfig :: handler_config(),
- Config :: handler_config(),
- Reason :: term().
-
--callback filter_config(Config) -> FilteredConfig when
- Config :: handler_config(),
- FilteredConfig :: handler_config().
-
--callback log(LogEvent, Config) -> term() when
- LogEvent :: log_event(), Config :: handler_config().
-
--callback removing_handler(Config) -> ok when
- Config :: handler_config().
-
%%%-----------------------------------------------------------------
%%% API
emergency(X) ->
@@ -399,7 +370,7 @@ add_primary_filter(FilterId,Filter) ->
logger_server:add_filter(primary,{FilterId,Filter}).
-spec add_handler_filter(HandlerId,FilterId,Filter) -> ok | {error,term()} when
- HandlerId :: handler_id(),
+ HandlerId :: logger_handler:id(),
FilterId :: filter_id(),
Filter :: filter().
add_handler_filter(HandlerId,FilterId,Filter) ->
@@ -412,20 +383,20 @@ remove_primary_filter(FilterId) ->
logger_server:remove_filter(primary,FilterId).
-spec remove_handler_filter(HandlerId,FilterId) -> ok | {error,term()} when
- HandlerId :: handler_id(),
+ HandlerId :: logger_handler:id(),
FilterId :: filter_id().
remove_handler_filter(HandlerId,FilterId) ->
logger_server:remove_filter(HandlerId,FilterId).
-spec add_handler(HandlerId,Module,Config) -> ok | {error,term()} when
- HandlerId :: handler_id(),
+ HandlerId :: logger_handler:id(),
Module :: module(),
- Config :: handler_config().
+ Config :: logger_handler:config().
add_handler(HandlerId,Module,Config) ->
logger_server:add_handler(HandlerId,Module,Config).
-spec remove_handler(HandlerId) -> ok | {error,term()} when
- HandlerId :: handler_id().
+ HandlerId :: logger_handler:id().
remove_handler(HandlerId) ->
logger_server:remove_handler(HandlerId).
@@ -447,31 +418,31 @@ set_primary_config(Config) ->
-spec set_handler_config(HandlerId,level,Level) -> Return when
- HandlerId :: handler_id(),
+ HandlerId :: logger_handler:id(),
Level :: level() | all | none,
Return :: ok | {error,term()};
(HandlerId,filter_default,FilterDefault) -> Return when
- HandlerId :: handler_id(),
+ HandlerId :: logger_handler:id(),
FilterDefault :: log | stop,
Return :: ok | {error,term()};
(HandlerId,filters,Filters) -> Return when
- HandlerId :: handler_id(),
+ HandlerId :: logger_handler:id(),
Filters :: [{filter_id(),filter()}],
Return :: ok | {error,term()};
(HandlerId,formatter,Formatter) -> Return when
- HandlerId :: handler_id(),
+ HandlerId :: logger_handler:id(),
Formatter :: {module(), formatter_config()},
Return :: ok | {error,term()};
(HandlerId,config,Config) -> Return when
- HandlerId :: handler_id(),
+ HandlerId :: logger_handler:id(),
Config :: term(),
Return :: ok | {error,term()}.
set_handler_config(HandlerId,Key,Value) ->
logger_server:set_config(HandlerId,Key,Value).
-spec set_handler_config(HandlerId,Config) -> ok | {error,term()} when
- HandlerId :: handler_id(),
- Config :: handler_config().
+ HandlerId :: logger_handler:id(),
+ Config :: logger_handler:config().
set_handler_config(HandlerId,Config) ->
logger_server:set_config(HandlerId,Config).
@@ -486,31 +457,31 @@ update_primary_config(Config) ->
logger_server:update_config(primary,Config).
-spec update_handler_config(HandlerId,level,Level) -> Return when
- HandlerId :: handler_id(),
+ HandlerId :: logger_handler:id(),
Level :: level() | all | none,
Return :: ok | {error,term()};
(HandlerId,filter_default,FilterDefault) -> Return when
- HandlerId :: handler_id(),
+ HandlerId :: logger_handler:id(),
FilterDefault :: log | stop,
Return :: ok | {error,term()};
(HandlerId,filters,Filters) -> Return when
- HandlerId :: handler_id(),
+ HandlerId :: logger_handler:id(),
Filters :: [{filter_id(),filter()}],
Return :: ok | {error,term()};
(HandlerId,formatter,Formatter) -> Return when
- HandlerId :: handler_id(),
+ HandlerId :: logger_handler:id(),
Formatter :: {module(), formatter_config()},
Return :: ok | {error,term()};
(HandlerId,config,Config) -> Return when
- HandlerId :: handler_id(),
+ HandlerId :: logger_handler:id(),
Config :: term(),
Return :: ok | {error,term()}.
update_handler_config(HandlerId,Key,Value) ->
logger_server:update_config(HandlerId,Key,Value).
-spec update_handler_config(HandlerId,Config) -> ok | {error,term()} when
- HandlerId :: handler_id(),
- Config :: handler_config().
+ HandlerId :: logger_handler:id(),
+ Config :: logger_handler:config().
update_handler_config(HandlerId,Config) ->
logger_server:update_config(HandlerId,Config).
@@ -526,8 +497,8 @@ get_primary_config() ->
maps:remove(handlers,Config).
-spec get_handler_config(HandlerId) -> {ok,Config} | {error,term()} when
- HandlerId :: handler_id(),
- Config :: handler_config().
+ HandlerId :: logger_handler:id(),
+ Config :: logger_handler:config().
get_handler_config(HandlerId) ->
case logger_config:get(?LOGGER_TABLE,HandlerId) of
{ok,#{module:=Module}=Config} ->
@@ -539,7 +510,7 @@ get_handler_config(HandlerId) ->
end.
-spec get_handler_config() -> [Config] when
- Config :: handler_config().
+ Config :: logger_handler:config().
get_handler_config() ->
[begin
{ok,Config} = get_handler_config(HandlerId),
@@ -547,7 +518,7 @@ get_handler_config() ->
end || HandlerId <- get_handler_ids()].
-spec get_handler_ids() -> [HandlerId] when
- HandlerId :: handler_id().
+ HandlerId :: logger_handler:id().
get_handler_ids() ->
{ok,#{handlers:=HandlerIds}} = logger_config:get(?LOGGER_TABLE,primary),
HandlerIds.
@@ -560,14 +531,14 @@ get_proxy_config() ->
-spec update_formatter_config(HandlerId,FormatterConfig) ->
ok | {error,term()} when
- HandlerId :: handler_id(),
+ HandlerId :: logger_handler:id(),
FormatterConfig :: formatter_config().
update_formatter_config(HandlerId,FormatterConfig) ->
logger_server:update_formatter_config(HandlerId,FormatterConfig).
-spec update_formatter_config(HandlerId,Key,Value) ->
ok | {error,term()} when
- HandlerId :: handler_id(),
+ HandlerId :: logger_handler:id(),
Key :: atom(),
Value :: term().
update_formatter_config(HandlerId,Key,Value) ->
@@ -677,7 +648,7 @@ unset_process_metadata() ->
ok.
-spec get_config() -> #{primary=>primary_config(),
- handlers=>[handler_config()],
+ handlers=>[logger_handler:config()],
proxy=>olp_config(),
module_levels=>[{module(),level() | all | none}]}.
get_config() ->
@@ -699,7 +670,7 @@ i() ->
i_modules(Modules,M).
-spec i(What) -> ok when
- What :: primary | handlers | proxy | modules | handler_id().
+ What :: primary | handlers | proxy | modules | logger_handler:id().
i(primary) ->
i_primary(get_primary_config(),modifier());
i(handlers) ->
diff --git a/lib/kernel/src/logger_disk_log_h.erl b/lib/kernel/src/logger_disk_log_h.erl
index 2f386acbf3..ca209ace8e 100644
--- a/lib/kernel/src/logger_disk_log_h.erl
+++ b/lib/kernel/src/logger_disk_log_h.erl
@@ -26,6 +26,8 @@
%%% API
-export([filesync/1]).
+-behaviour(logger_handler).
+
%% logger_h_common callbacks
-export([init/2, check_config/4, reset_state/2,
filesync/3, write/4, handle_info/3, terminate/3]).
@@ -70,7 +72,7 @@ removing_handler(Config) ->
%%% Log a string or report
-spec log(LogEvent,Config) -> ok when
LogEvent :: logger:log_event(),
- Config :: logger:handler_config().
+ Config :: logger_handler:config().
log(LogEvent,Config) ->
logger_h_common:log(LogEvent,Config).
diff --git a/lib/kernel/src/logger_h_common.erl b/lib/kernel/src/logger_h_common.erl
index 3c99d49f3d..99c258c40f 100644
--- a/lib/kernel/src/logger_h_common.erl
+++ b/lib/kernel/src/logger_h_common.erl
@@ -168,7 +168,7 @@ changing_config(SetOrUpdate,
%%% Log a string or report
-spec log(LogEvent, Config) -> ok when
LogEvent :: logger:log_event(),
- Config :: logger:handler_config().
+ Config :: logger_handler:config().
log(LogEvent, Config = #{config := #{olp:=Olp}}) ->
%% if the handler has crashed, we must drop this event
@@ -379,7 +379,7 @@ log_handler_info(Name, Format, Args, #{module:=Module,
%%% Convert log data on any form to binary
-spec log_to_binary(LogEvent,Config) -> LogString when
LogEvent :: logger:log_event(),
- Config :: logger:handler_config(),
+ Config :: logger_handler:config(),
LogString :: binary().
log_to_binary(#{msg:={report,_},meta:=#{report_cb:=_}}=Log,Config) ->
do_log_to_binary(Log,Config);
diff --git a/lib/kernel/src/logger_handler.erl b/lib/kernel/src/logger_handler.erl
new file mode 100644
index 0000000000..f8aef0fe6e
--- /dev/null
+++ b/lib/kernel/src/logger_handler.erl
@@ -0,0 +1,61 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2023-2023. All Rights Reserved.
+%%
+%% 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.
+%%
+%% %CopyrightEnd%
+%%
+-module(logger_handler).
+
+%%%
+%%% Types
+-type config() :: #{id => id(),
+ config => term(),
+ level => logger:level() | all | none,
+ module => module(),
+ filter_default => log | stop,
+ filters => [{logger:filter_id(),logger:filter()}],
+ formatter => {module(),logger:formatter_config()}}.
+-type id() :: atom().
+
+-export_type([config/0, id/0]).
+
+%%%-----------------------------------------------------------------
+%%% Callbacks
+-callback adding_handler(Config1) -> {ok, Config2} | {error, Reason} when
+ Config1 :: config(),
+ Config2 :: config(),
+ Reason :: term().
+
+-callback changing_config(SetOrUpdate, OldConfig, NewConfig) ->
+ {ok, Config} | {error, Reason} when
+ SetOrUpdate :: set | update,
+ OldConfig :: config(),
+ NewConfig :: config(),
+ Config :: config(),
+ Reason :: term().
+
+-callback filter_config(Config) -> FilteredConfig when
+ Config :: config(),
+ FilteredConfig :: config().
+
+-callback log(LogEvent, Config) -> term() when
+ LogEvent :: logger:log_event(), Config :: config().
+
+-callback removing_handler(Config) -> ok when
+ Config :: config().
+
+-optional_callbacks([adding_handler/1, changing_config/3,
+ filter_config/1, removing_handler/1]).
diff --git a/lib/kernel/src/logger_handler_watcher.erl b/lib/kernel/src/logger_handler_watcher.erl
index 6f622b169c..1e4cd4ce48 100644
--- a/lib/kernel/src/logger_handler_watcher.erl
+++ b/lib/kernel/src/logger_handler_watcher.erl
@@ -43,7 +43,7 @@
start_link() ->
gen_server:start_link({local, ?SERVER}, ?MODULE, [], []).
--spec register_handler(Id::logger:handler_id(),Pid::pid()) -> ok.
+-spec register_handler(Id :: logger_handler:id(), Pid :: pid()) -> ok.
register_handler(Id,Pid) ->
gen_server:call(?SERVER,{register,Id,Pid}).
diff --git a/lib/kernel/src/logger_simple_h.erl b/lib/kernel/src/logger_simple_h.erl
index d35c533b6d..cd677e505b 100644
--- a/lib/kernel/src/logger_simple_h.erl
+++ b/lib/kernel/src/logger_simple_h.erl
@@ -21,6 +21,8 @@
-export([adding_handler/1, removing_handler/1, log/2]).
+-behaviour(logger_handler).
+
%% This module implements a simple handler for logger. It is the
%% default used during system start.
diff --git a/lib/kernel/src/logger_std_h.erl b/lib/kernel/src/logger_std_h.erl
index 1b2fabad72..d90f9b2acb 100644
--- a/lib/kernel/src/logger_std_h.erl
+++ b/lib/kernel/src/logger_std_h.erl
@@ -28,6 +28,8 @@
%% API
-export([filesync/1]).
+-behaviour(logger_handler).
+
%% logger_h_common callbacks
-export([init/2, check_config/4, config_changed/3, reset_state/2,
filesync/3, write/4, handle_info/3, terminate/3]).
@@ -58,7 +60,7 @@ filesync(Name) ->
%%%-----------------------------------------------------------------
%%% Handler being added
-spec adding_handler(Config) -> {ok,Config} | {error,Reason} when
- Config :: logger:handler_config(),
+ Config :: logger_handler:config(),
Reason :: term().
adding_handler(Config) ->
@@ -69,9 +71,9 @@ adding_handler(Config) ->
-spec changing_config(SetOrUpdate, OldConfig, NewConfig) ->
{ok,Config} | {error,Reason} when
SetOrUpdate :: set | update,
- OldConfig :: logger:handler_config(),
- NewConfig :: logger:handler_config(),
- Config :: logger:handler_config(),
+ OldConfig :: logger_handler:config(),
+ NewConfig :: logger_handler:config(),
+ Config :: logger_handler:config(),
Reason :: term().
changing_config(SetOrUpdate, OldConfig, NewConfig) ->
@@ -80,7 +82,7 @@ changing_config(SetOrUpdate, OldConfig, NewConfig) ->
%%%-----------------------------------------------------------------
%%% Handler being removed
-spec removing_handler(Config) -> ok when
- Config :: logger:handler_config().
+ Config :: logger_handler:config().
removing_handler(Config) ->
logger_h_common:removing_handler(Config).
@@ -89,7 +91,7 @@ removing_handler(Config) ->
%%% Log a string or report
-spec log(LogEvent, Config) -> ok when
LogEvent :: logger:log_event(),
- Config :: logger:handler_config().
+ Config :: logger_handler:config().
log(LogEvent, Config) ->
logger_h_common:log(LogEvent, Config).
@@ -97,7 +99,7 @@ log(LogEvent, Config) ->
%%%-----------------------------------------------------------------
%%% Remove internal fields from configuration
-spec filter_config(Config) -> Config when
- Config :: logger:handler_config().
+ Config :: logger_handler:config().
filter_config(Config) ->
logger_h_common:filter_config(Config).
--
2.35.3