Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Honeybadger.Logger process starts in wrong environments and terminates/times out for no clear reason #248

Open
kwayebopp opened this issue Dec 9, 2019 · 4 comments
Labels

Comments

@kwayebopp
Copy link

Hi! I have an Elixir/Phoenix app using Honeybadger for error reporting and logging. During development (and I suspect occasionally in production) the server throws a DBConnection.ConnectionError. This happens from time to time, and I'm working on optimizing queries. What is strange is that I see the Honeybadger application is running as well, as I've tried to disable it in the development environment.

Here's an example of one such error:

[info] Postgrex.Protocol (#PID<0.435.0>) disconnected: ** (DBConnection.ConnectionError) client #PID<0.1575.0> exited
[error] #PID<0.1563.0> running CoolAppWeb.Endpoint (connection #PID<0.1548.0>, stream id 3) terminated
Server: subdomain.localhost:4000 (http)
Request: POST /graphql
** (exit) exited in: Task.await(%Task{owner: #PID<0.1563.0>, pid: #PID<0.1575.0>, ref: #Reference<0.3695852442.3919314945.95728>}, 5000)
** (EXIT) time out
[error] :gen_event handler Honeybadger.Logger installed in Logger terminating
** (FunctionClauseError) no function clause matching in Honeybadger.Notice.new/3
(honeybadger) lib/honeybadger/notice.ex:36: Honeybadger.Notice.new(:timeout, %{context: %{}}, {Task, :await, [%Task{owner: #PID<0.1563.0>, pid: #PID<0.1575.0>, ref: #Reference<0.3695852442.3919314945.95728>}, 5000]})
(honeybadger) lib/honeybadger.ex:207: Honeybadger.notify/3
(honeybadger) lib/honeybadger/logger.ex:35: Honeybadger.Logger.handle_event/2
(stdlib) gen_event.erl:577: :gen_event.server_update/4
(stdlib) gen_event.erl:559: :gen_event.server_notify/4
(stdlib) gen_event.erl:300: :gen_event.handle_msg/6
(stdlib) proc_lib.erl:249: :proc_lib.init_p_do_apply/3
Last message: {:error, #PID<0.427.0>, {Logger, ["#PID<0.1563.0>", " running ", "CoolAppWeb.Endpoint", [" (connection ", "#PID<0.1548.0>", ", stream id ", "3", 41], " terminated\n", [["Server: ", "subdomain.localhost", ":", "4000", 32, 40, "http", 41, 10], ["Request: ", "POST", 32, "/graphql", 10]] | "** (exit) exited in: Task.await(%Task{owner: #PID<0.1563.0>, pid: #PID<0.1575.0>, ref: #Reference<0.3695852442.3919314945.95728>}, 5000)\n ** (EXIT) time out"], {{2019, 12, 6}, {12, 39, 18, 576}}, [crash_reason: {:timeout, {Task, :await, [%Task{owner: #PID<0.1563.0>, pid: #PID<0.1575.0>, ref: #Reference<0.3695852442.3919314945.95728>}, 5000]}}, pid: #PID<0.1548.0>]}}
State: %{level: nil}
[error] GenServer #PID<0.409.0> terminating
** (stop) {:EXIT, {:function_clause, [{Honeybadger.Notice, :new, [:timeout, %{context: %{}}, {Task, :await, [%Task{owner: #PID<0.1563.0>, pid: #PID<0.1575.0>, ref: #Reference<0.3695852442.3919314945.95728>}, 5000]}], [file: 'lib/honeybadger/notice.ex', line: 36]}, {Honeybadger, :notify, 3, [file: 'lib/honeybadger.ex', line: 207]}, {Honeybadger.Logger, :handle_event, 2, [file: 'lib/honeybadger/logger.ex', line: 35]}, {:gen_event, :server_update, 4, [file: 'gen_event.erl', line: 577]}, {:gen_event, :server_notify, 4, [file: 'gen_event.erl', line: 559]}, {:gen_event, :handle_msg, 6, [file: 'gen_event.erl', line: 300]}, {:proc_lib, :init_p_do_apply, 3, [file: 'proc_lib.erl', line: 249]}]}}
Last message: {:gen_event_EXIT, Honeybadger.Logger, {:EXIT, {:function_clause, [{Honeybadger.Notice, :new, [:timeout, %{context: %{}}, {Task, :await, [%Task{owner: #PID<0.1563.0>, pid: #PID<0.1575.0>, ref: #Reference<0.3695852442.3919314945.95728>}, 5000]}], [file: 'lib/honeybadger/notice.ex', line: 36]}, {Honeybadger, :notify, 3, [file: 'lib/honeybadger.ex', line: 207]}, {Honeybadger.Logger, :handle_event, 2, [file: 'lib/honeybadger/logger.ex', line: 35]}, {:gen_event, :server_update, 4, [file: 'gen_event.erl', line: 577]}, {:gen_event, :server_notify, 4, [file: 'gen_event.erl', line: 559]}, {:gen_event, :handle_msg, 6, [file: 'gen_event.erl', line: 300]}, {:proc_lib, :init_p_do_apply, 3, [file: 'proc_lib.erl', line: 249]}]}}}
State: {Logger, Honeybadger.Logger}

As stated above, I tried to take measures to ensure that Honeybadger doesn't run during development. In mix.exs a function is used to collect the appropriate extra_applications:

mix.exs:

  defp get_extra_applications do
    apps = [
      :logger,
      :runtime_tools,
      #some other applications...
    ]

    case Mix.env() do
      :prod -> apps ++ [:honeybadger] # we only want honeybadger running in production
      :test -> apps ++ [:ex_machina] 
      :dev -> apps
    end
  end

  def application do
    [
      mod: {CoolApp.Application, []},
      extra_applications: get_extra_applications()
    ]
  end

In addition to that, I tried to make sure that the Honeybadger.Plug is only conditionally used in router.ex:

defmodule CoolAppWeb.Router do
  use CoolAppWeb, :router

  if Mix.env() === :prod do # only use the plug in production
    use Honeybadger.Plug
  end

...

This behavior is probably not correct, so I think I maybe have something wrong in my setup somewhere. In the interest of putting everything up for examination I've included the dev and prod configs.

config.exs:

config :honeybadger,
app: :cool_app,
exclude_envs: [:dev, :test],
filter: Honeybadger.Filter.Default,
filter_keys: [:password],
api_key: System.get_env("HONEYBADGER_API_KEY")

dev.exs:

config :cool_app, CoolApp.Repo,
  adapter: Ecto.Adapters.Postgres,
  username: ...,
  password: ...,
  database: ...,
  hostname: "localhost",
  pool_size: String.to_integer(System.get_env("POOL_SIZE") || "10"),
  queue_target: 5_000

config :honeybadger, environment_name: :dev

prod.exs:

config :cool_app, CoolApp.Repo,
  adapter: Ecto.Adapters.Postgres,
  url: System.get_env("DATABASE_URL"),
  pool_size: String.to_integer(System.get_env("POOL_SIZE") || "10"),
  ssl: true,
  queue_target: 5_000

config :honeybadger, environment_name: :prod

This problem is a real head-scratcher for me, so any and all help or suggestions are greatly appreciated!

@kwayebopp kwayebopp changed the title Honeybadger.Logger process terminates/times out for no clear reason Honeybadger.Logger process starts in wrong environments and terminates/times out for no clear reason Dec 9, 2019
@sorentwo
Copy link
Collaborator

sorentwo commented Dec 9, 2019

You can disable the logger in dev:

config :honeybadger, environment_name: :dev, use_logger: false

However, that shouldn't be necessary. The logger shouldn't ever crash when attempting to send a notice. I'm curious how the call to Notice.new/3 got a single stack line and not a list of stacklines:

(honeybadger) lib/honeybadger/notice.ex:36: Honeybadger.Notice.new(:timeout, %{context: %{}}, {Task, :await, [%Task{owner: #PID<0.1563.0>, pid: #PID<0.1575.0>, ref: #Reference<0.3695852442.3919314945.95728>}, 5000]})

I have a potential fix for that issue ready, but I can't recreate it with any tests.

@kwayebopp
Copy link
Author

Looking at the line, the error is a timeout, and the integer at the end is the same value as my :queue_target config. Maybe that has something to do with it?

@sorentwo
Copy link
Collaborator

That is the format of every error tuple in a stacktrace. The strange part is that it isn't part of a list.

@joshuap joshuap added the bug label Mar 10, 2020
@jimmybot
Copy link

jimmybot commented Mar 12, 2021

Here to chime in that we just experienced a similar issue where the Honeybadger.Notice.new call fails because the stacktrace is a tuple and not a list.

** (FunctionClauseError) no function clause matching in Honeybadger.Notice.new/4
    (honeybadger 0.15.0) lib/honeybadger/notice.ex:38: Honeybadger.Notice.new(:timeout, %{breadcrumbs: %{enabled: true, trail: [%Honeybadger.Breadcrumbs.Breadcrumb{category: "error", message: "ErlangError", metadata: %{message: "Erlang error: :timeout"}, timestamp: ~U[2021-03-12 16:26:05.940350Z]}, %Honeybadger.Breadcrumbs.Breadcrumb{category: "notice", message: "Honeybadger Notice: timeout", metadata: %{}, timestamp: ~U[2021-03-12 16:26:05.940373Z]}]}, context: %{domain: [:cowboy], erl_level: :error, error_logger: %{tag: :error}, gl: #PID<0.444.0>, report_cb: #Function<0.118689316/1 in :error_logger."-fun.report_to_format/1-">, time: 1615566365940243}}, {GenServer, :call, [:XXX, {:valid_account, "XXX:XXX"}, 5000]}, "")
    (honeybadger 0.15.0) lib/honeybadger.ex:297: Honeybadger.notify/2
    (honeybadger 0.15.0) lib/honeybadger/logger.ex:37: Honeybadger.Logger.handle_event/2
    (stdlib 3.13.2) gen_event.erl:620: :gen_event.server_update/4
    (stdlib 3.13.2) gen_event.erl:602: :gen_event.server_notify/4
    (stdlib 3.13.2) gen_event.erl:343: :gen_event.handle_msg/6
    (stdlib 3.13.2) proc_lib.erl:226: :proc_lib.init_p_do_apply/3

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

4 participants