From fa9e88f674920a3f79451371385b9747da825efb Mon Sep 17 00:00:00 2001 From: Pierre Allix Date: Mon, 28 Jan 2019 16:41:15 +0100 Subject: [PATCH 1/2] Fix logger not working after a call to `Logger.configure_backends` --- lib/syslog.ex | 55 ++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 39 insertions(+), 16 deletions(-) diff --git a/lib/syslog.ex b/lib/syslog.ex index e82238d..65d59e5 100644 --- a/lib/syslog.ex +++ b/lib/syslog.ex @@ -3,18 +3,30 @@ defmodule Logger.Backends.Syslog do use Bitwise + defstruct format: nil, + metadata: nil, + level: nil, + socket: nil, + host: nil, + port: nil, + facility: nil, + appid: nil, + hostname: nil + def init(_) do + config = Application.get_env(:logger, :syslog) + if user = Process.whereis(:user) do Process.group_leader(self(), user) {:ok, socket} = :gen_udp.open(0) - {:ok, configure([socket: socket])} + {:ok, init(config, %__MODULE__{socket: socket})} else {:error, :ignore} end end - def handle_call({:configure, options}, _state) do - {:ok, :ok, configure(options)} + def handle_call({:configure, options}, state) do + {:ok, :ok, configure(options, state)} end def handle_event({_level, gl, _event}, state) when node(gl) != node() do @@ -34,24 +46,35 @@ defmodule Logger.Backends.Syslog do ## Helpers - defp configure(options) do - syslog = Keyword.merge(Application.get_env(:logger, :syslog, []), options) - socket = Keyword.get(options, :socket) - Application.put_env(:logger, :syslog, syslog) + defp configure(options, state) do + config = Keyword.merge(Application.get_env(:logger, :syslog, []), options) + Application.put_env(:logger, :syslog, config) + init(config, state) + end - format = syslog + defp init(config, state) do + format = config |> Keyword.get(:format) |> Logger.Formatter.compile - level = Keyword.get(syslog, :level) - metadata = Keyword.get(syslog, :metadata, []) - host = Keyword.get(syslog, :host, '127.0.0.1') - port = Keyword.get(syslog, :port, 514) - facility = Keyword.get(syslog, :facility, :local2) |> Logger.Syslog.Utils.facility - appid = Keyword.get(syslog, :appid, :elixir) + level = Keyword.get(config, :level) + metadata = Keyword.get(config, :metadata, []) + host = Keyword.get(config, :host, '127.0.0.1') + port = Keyword.get(config, :port, 514) + facility = Keyword.get(config, :facility, :local2) |> Logger.Syslog.Utils.facility + appid = Keyword.get(config, :appid, :elixir) [hostname | _] = String.split("#{:net_adm.localhost()}", ".") - %{format: format, metadata: metadata, level: level, socket: socket, - host: host, port: port, facility: facility, appid: appid, hostname: hostname} + + %{state | + format: format, + metadata: metadata, + level: level, + socket: state.socket, + host: host, + port: port, + facility: facility, + appid: appid, + hostname: hostname} end defp log_event(level, msg, ts, md, state) do From 9ef5aa52e4659fae22c48845e5522c6641f7bc1f Mon Sep 17 00:00:00 2001 From: Pierre Allix Date: Mon, 28 Jan 2019 17:01:39 +0100 Subject: [PATCH 2/2] Ensure socket is closed when logger backend is removed --- lib/syslog.ex | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/lib/syslog.ex b/lib/syslog.ex index 65d59e5..35080ba 100644 --- a/lib/syslog.ex +++ b/lib/syslog.ex @@ -44,6 +44,12 @@ defmodule Logger.Backends.Syslog do {:ok, state} end + def terminate(_, state) do + socket = state.socket + if socket, do: :gen_udp.close(socket) + :ok + end + ## Helpers defp configure(options, state) do