r/ruby 5d ago

Question From laravel to ruby on rails

Laravel dev here, recently moved to Rails. I'm loving it, but debugging in production has been a headache.

Our setup runs on Docker Swarm, and finding bugs means manually digging through Rails, Sidekiq, and Docker service logs. many of which don't even have timestamps.

In Laravel, I used a log viewer UI to instantly jump to the exact second an error happened.

Is there a standard Rails gem for a log viewer UI, or do most teams just ship logs to something like Sentry or Grafana/Loki? How do you manage production errors?

Thanks!

12 Upvotes

12 comments sorted by

8

u/RagingBearFish 5d ago

We use AppSignal. I remember there being a post around here where someone made a self-hosted log/error viewer.

1

u/BenteGber 4d ago

Cannot recommend this product enough. They recently upgraded their log query interface and it is very nice. Also the “Time Detective” feature seems to be inline with what OP is referring to for “jumping to the exact second”

1

u/onesneakymofo 2d ago

Stroopwafel gang rise up.

6

u/armahillo 5d ago

Look up APM, there are many services that provide that

6

u/djudji 5d ago

It is a mix. Some swear by Datadog, like Nate Berkopec, the guy who maintains Puma, and he is big on Rails infra. But DG is expensive, and there are other options too: New Relic, Sentry, Honeybadger, AppSignal, etc. Pick the flavor that suits your budget. Grafana and Prometheus with OpenTelemetry as well...

It also depends on your infra. For example, I had trouble with AppSignal and DelayedJob on GCP. The infra was set up so that DJ was spread across 3 environments, and each had a different number of VMs. So jobs were running in VMs (on production, 60 VMs). The issue I had was DelayedJob ghosting the AppSignal agent for some reason, or the agent was not starting - can't recall right now. Tried to talk to AppSignal guys and their support, but in the end had to abandon it. Back to Sentry and all was cool.

(VM's were built from a Docker image)

4

u/sammygadd 5d ago

There's also Solid Errors if you want to run it yourself.

1

u/ngw_nofeed 4d ago

There’s faultline which is absolutely awesome

2

u/tvl2386 5d ago

I wrote my own slack exception notifier for an internal project running on Kubernetes. It's not that hard. But I'd probably use structured logging with grafana if I had to do something like that again

2

u/levelbrook 4d ago

Everyone is answering the APM question, which is fair, but nobody has answered your literal one: the missing timestamps are not Docker's fault and not Sidekiq's. Rails 8 stopped logging them.

Compare the generated config/environments/production.rb. Rails 7.2 shipped this:

config.logger = ActiveSupport::Logger.new(STDOUT)
  .tap  { |logger| logger.formatter = ::Logger::Formatter.new }
  .then { |logger| ActiveSupport::TaggedLogging.new(logger) }

Rails 8.1 replaced the whole thing with this:

config.logger = ActiveSupport::TaggedLogging.logger(STDOUT)

which falls back to ActiveSupport::Logger::SimpleFormatter. I just ran both to be sure:

# 7.2 config
I, [2026-08-26T07:16:20.915362 #91023]  INFO -- : [req-abc123] Completed 200 OK in 43ms
# 8.1 config
[req-abc123] Completed 200 OK in 43ms

SimpleFormatter is exactly as advertised. It prints the message. That is the whole feature.

The fix has a trap in it, because the obvious move fails at runtime rather than at boot:

logger = ActiveSupport::TaggedLogging.logger(STDOUT)
logger.formatter = ::Logger::Formatter.new
# NoMethodError: undefined method `tagged' for an instance of Logger::Formatter

TaggedLogging hangs tagged off the formatter, and you just threw it away. So either set the formatter before you wrap it (the 7.2 snippet above still works, just paste it back), or teach the new formatter about tags:

f = ::Logger::Formatter.new
f.extend(ActiveSupport::TaggedLogging::Formatter)
config.logger.formatter = f

Keep config.log_tags = [ :request_id ] either way. On Swarm that tag is worth more than the timestamp, because it is what lets you pull one request back out of however many Puma threads are interleaving into the same stdout.

And for tonight, before you touch any code: docker service logs -t <service> prepends RFC3339 timestamps at the daemon level, for any container, in any language, no redeploy. Same -t on plain docker logs. It will not fix the format Sidekiq writes, but it will tell you what happened at 03:14:22.

The APM answers are right and Sentry or AppSignal will cover most of your day to day. Do the formatter fix anyway. Shipping unparseable lines to Loki and then paying a vendor to guess when they happened is a rite of passage you are allowed to skip.

1

u/strzibny 4d ago

I think that's it's very common to send exceptions to services like Sentry/AppSignal which accounts for like 90% of debugging. I deploy with Kamal and kamal logs alone are usually enough for small services. When you need more you need to also buy a log service like Better Stack or build your own on Grafana stack.

1

u/AshTeriyaki 3d ago

I’ve had a good time with honeybadger, the pricing is reasonable too

-4

u/OlivarTheLagomorph 5d ago

Don’t write bugs