Eiji

Eiji

Questions about Elixir Logger

Hey, I tried to debug how I can catch some things.
I created a new local application by mix new my_logger command.
My config/config.exs:

use Mix.Config

config :logger,
  backends: [MyLogger],
  handle_otp_reports: true,
  handle_sasl_reports: true

and here is my main module:

defmodule MyLogger do
  use GenEvent

  def init(_) do
    {:ok, %{}}
  end

  def handle_call({:configure, options}, _state) do
    {:ok, :ok, %{}}
  end

  def handle_event({_level, gl, {Logger, _, _, _}}, state) when node(gl) != node() do
    {:ok, state}
  end
  def handle_event({level, group_leader, {Logger, message, {date, time}, details}}, state) do
    IO.inspect "catched?"
    # stacktrace here ...
    {:ok, state}
  end
end

at end I run iex -S mix command.
In Interactive Elixir I can see already catched 3 log messages.
It works also when I try to execute an: Logger macros such as info.
I checked what data I could collect and it’s really good.
From here I have some questions:

  1. I know that &System.stacktrace/0 works only for exceptions. Is there any other way (logger configuration?) to get a stacktrace when message is logged?
  2. Is there any way to catch also all raise (I mean allow crash, but send info about it to Logger). I already tried set some logger configuration variables like @OvermindDL1 already wrote, but I don’t got a “catched?” message.
  3. Is it possible (by configuration change?) to got passed argument values in stacktrace (optionally only for Logger), so I could easily reproduce an logged message in user specific situations?

Marked As Solved

OvermindDL1

OvermindDL1

Unsure about that, worst case you could throw and catch an exception to get a stacktrace… sounds slow though

Any uncaught raise’s or any uncaught exception in general should kill its process and log to :sasl, which you can catch through there. However ‘caught’ exceptions are ‘caught’, thus handled, thus nothing reported, so you will never get a ‘catched’ message of any form, only uncaught exceptions. You’d have to decorate raise with a replacement macro or something to do that I’d think?

Stacktraces do not hold that much information, especially because that information might be gone by the time the exception is thrown if those names end up unused by the point the exception is thrown and, say, garbage collected, so I’m unsure if that would even be possible in all cases. At the very least you should have the information for the current application, module, function name, file name, and line number of a log, beyond that you need to add the extra information yourself (which you could easily add the passed in arguments to by adding them to the process log of metadata by calling something like Logger.metadata([:func_args, [blah, bleep]]) but that will get overwritten of course if calling any other function before that point. If you made a custom function (replace def with your own) then you could decorate a log call as much as you want safely, but you’d have to change your function definitions everywhere that you’d want to log that information. Remember that Elixir is about explicitness, minimize magical stuff. :slight_smile:

I could easily be wrong on much of this, I use Logger to log, I’ve not made my own back-end yet. ^.^

Also Liked

OvermindDL1

OvermindDL1

You’d have to do it at the call site via a custom log function, it would not work within your logger. Sorry I forgot to say that. :-)[quote=“Eiji, post:3, topic:2237”]
hmm, I would like to catch all raise without try dorescueend code.
I do not expect too many mistakes, but I want to catch them all like Pokemons trainer :smile:
[/quote]

Hehe, you should be able to by turning on :sasl and such. Raise’s without try’s will eventually kill the process that it is in, which will be reported by :sasl. If it does not kill the process then there was a try that caught it. :slight_smile:

The pointer honestly probably still exists on the stack itself until the function returns (thus no GC’ing it), but no clue how it would be accessible as for all intents and purposes it is dead at those times after its last use. A custom log function/macro could keep it alive though, but I’m pretty sure that would require a custom def regardless unless you use one of the :after_compile hooks or so…

OvermindDL1

OvermindDL1

The shell, sadly, does not live on an OTP tree (it lives ‘in’ it, but not managed by it, it is manually managed), so you will not get messages from it, but you will from anything attached to the OTP tree. :slight_smile:

You could easily make a defLog or so macro that people can replaced def with that adds in all kinds of extra useful log metadata or so (and clears it when it exits). :slight_smile:

That, to me, would be quite beautiful. :slight_smile:

Where Next?

Popular in Questions Top

shahryarjb
Hello, I get Persian date from my client and convert it to normal calendar like this: def jalali_string_to_miladi_english_number(persi...
New
jerry
Good day to you all. I have been struggling to get a query involving like and ilike to work. Can anyone assist me on this, please? pro...
New
quazar
How to set Jason to encode all fields in ecto schema, I don’t care about security and implementing only is taking long list of attributes...
New
dokuzbir
Hello, I am trying to convert my lists to string without losing brackets.For start i have 3 map. They look like these buyer = %{ id: ...
New
vertexbuffer
Hello, can anybody help here..? I have a list of players and I what to delete an element, but every for loop the list is reverting to ori...
New
makeitrein
Hey all, just started picking up Elixir last week and am writing a scraper as a learning project. Baby step #1 is extracting the number ...
New
johnnyicon
Hi all, I've just started learning Elixir and Phoenix Framework, so please pardon my n00bness at this stage. I'm trying to use Postg...
New
ovidiubadita
Hey all, I discovered Elixir and I love it. I always wanted to learn a functional programming and I intended to go for Haskell, but afte...
New
electic
Hi, I am new to Elixir. I am trying to use the DateTime component to insert a date into MySQL however the there seems to be no way to fo...
New
Patoshizzle
After calling mix ecto.create I get this error: 17:00:32.162 [error] GenServer #PID<0.412.0> terminating ** (Postgrex.Error) FATAL...
New

Other popular topics Top

peerreynders
Manning 2016 Halloween weekend sale via Deal of the Day Friday, October 28 - Half off all MEAPs - code WM102816LT Saturday, October 29 ...
326 29600 154
New
sergio
In Ruby, I can go: User.find_by(email: "foobar@email.com").update(email: "hello@email.com") How can I do something similar in Elixir? ...
New
Tee
can someone please explain to me how Enum.reduce works with maps
New
gshaw
What is the idiomatic way of matching for not nil in Elixir? E.g., First way: defp halt_if_not_signed_in(conn, signed_in_account) when...
New
KronicDeth
Elixir plugin for JetBrain’s IntelliJ Platform (including Rubymine) This is a plugin that adds support for Elixir to JetBrains IntelliJ...
289 35421 110
New
quazar
How to set Jason to encode all fields in ecto schema, I don’t care about security and implementing only is taking long list of attributes...
New
chrismccord
This release brings a number of exciting features, including integration with the new Phoenix LiveDashboard and Phoenix LiveView. There h...
New
msaraiva
Surface is an experimental library built on top of Phoenix LiveView and its new LiveComponent API that aims to provide a more declarative...
564 42633 214
New
chrisalley
ExUnit now has describe blocks which is a welcome addition coming from RSpec. In the docs, it states that nested hierarchies of describe ...
New
aesmail
Hello guys, I have finally made it. I created an admin interface for a framework. It’s been on my todo list for years and with the curre...
New

We're in Beta

About us Mission Statement