7

I need to get line numbers for IO.puts or IO.inspect or any other kind of output that appears on elixir console for the purpose of debugging. Is there an in-built feature for this? Or is there any other easy way to achieve the same?

P.S: By Line Number for IO.puts, I mean the line where IO.puts is written in the code.

Kshitij Mittal
  • 2,698
  • 3
  • 25
  • 40

1 Answers1

11

You're probably looking for __ENV__, which will give you access to the current file and line (among other things). You could do something like this:

Logger.debug("#{__ENV__.file}:#{__ENV__.line}: #{inspect some_value}")

Edit: as José suggested in the comments, the better way to do this is to use the metadata feature of logger. At the moment, you can only add the :module, :function and :line keys:

# config/config.exs

config :logger, :console, metadata: [:module, :function, :line]

However, I made a PR to add the :file key as well. It is already merged and should be released with the next version of Elixir. With the new version you can do

# config/config.exs

config :logger, :console, metadata: [:file, :line]
Patrick Oscity
  • 53,604
  • 17
  • 144
  • 168
  • 1
    Keep in mind that `Logger` already includes both file and line in the metadata. You can include it in your reports by adding both file and line to your metadata configuration in logger. – José Valim Nov 06 '15 at 14:01
  • @JoséValim you mean this right? `config :logger, :console, metadata: [:module, :function, :line]` – Patrick Oscity Nov 06 '15 at 14:19
  • Unfortunately it seems impossible to add the file this way. – Patrick Oscity Nov 06 '15 at 14:19
  • :file works, but it holds the complete path. How would I drop the path and only log the filename and extension? – raarts Mar 08 '17 at 21:41
  • AFAIK you need to do this manually, as in my first example. You can write a macro to avoid repetition, there you can use `__CALLER__` instead of `__ENV__` which should give you the file and line at the point where the macro was called. To extract just the filename you can use `Path.basename/1`, but be aware that the generated output will be ambiguous for equally nsmed files in differing directories. – Patrick Oscity Mar 08 '17 at 23:17
  • I was wondering why the only file I see is the `logger.ex`. Then I changed an `IO.inspect` to `Logger.debug` and it started to show the actual file the log was put into. Any way to make that work for `IO.inspect` as expected? – Jared Nov 23 '21 at 15:53
  • The OP says he's looking for `IO.puts` but isn't this for the logger? Isn't logger a tottaly different thing? Sorry if I'm wrong. I also have the same question as the OP re: `IO.puts`. This doesn't appear to solve that. – Mote Zart Jun 29 '23 at 19:43
  • @MoteZart it does not matter how you present the output, `__ENV__` contains the file and line number of the currently executing code. If you happen to use Logger, it's more convenient if you want file and line numbers on all debugging output to just configure that in one place. – Patrick Oscity Jun 30 '23 at 00:03