How can I configure Erlang's error_logger to persist logs to a file for post‑mortem analysis of a failed deployment?
0 reputation · 07 Apr 2023, 07:39 UTC
0 reputation · 07 Apr 2023, 07:39 UTC
When an Erlang release fails during deployment, the default error_logger output goes to the console and can be lost if the node terminates abruptly. To diagnose the failure later, I need to capture error_logger events in a file that survives node crashes and is available for offline inspection.
Using error_logger:logfile/1 redirects logs to a file, but I am uncertain about its write semantics (append vs. truncate), whether it flushes after each entry, and if it guarantees persistence before a node stops. Additionally, I want to know whether adding a custom report handler with error_logger:add_report_handler/2 after the application starts is safe, or if it must be installed in the boot script to catch early boot events.
Does error_logger:logfile/2 open the file in append mode and flush after each write? How can I guarantee that log entries are persisted to disk before the node stops? Is it safe to add a report handler via error_logger:add_report_handler/2 after the application starts, or must it be done in the boot script?
26525 reputation · 07 Apr 2023, 12:08 UTC
To redirect Erlang's error_logger output to a file that survives node termination, use the error_logger:logfile/1 function. This redirects the standard error output to the specified file path.
error_logger:logfile("error.log").
Based on standard error_logger behavior in legacy OTP versions:
error_logger:logfile/1 opens the file in append mode. It does not truncate existing logs upon node restart, which is critical for post-mortem analysis across multiple crash cycles.fsync after every single entry. In the event of a catastrophic OS kernel panic, the very last few entries may be lost, but for standard Erlang VM crashes or process terminations, the buffered data is typically flushed by the OS.If you are using error_logger:add_report_handler/2 to implement a custom logging strategy, the timing of the call is critical:
sys.config file.To verify that your configuration is active and persisting data, run the following in your shell:
error_logger:logfile("debug_test.log").error_logger:error_msg("Verification test entry").cat debug_test.logThe error_logger module is considered legacy in Erlang/OTP 21 and later. If you are using a modern version, it is highly recommended to migrate to the logger module, which provides more robust handler configurations and built-in support for log rotation to prevent disk exhaustion.
Diagnostic Detail Needed: Please specify your Erlang/OTP version. If you are on OTP 21+, the recommendation shifts entirely toward the logger framework for guaranteed persistence and rotation.
Use comments to ask for clarification. Post a solution as an answer.
26,525 reputation · 07 Apr 2023, 12:07 UTC
The most straightforward way to persist error_logger output is to redirect its tty to a file:
error_logger:tty({file,"/var/log/erlang/error.log"}).
This call opens the file in append mode and writes every error log entry immediately to it. The console output is suppressed unless you set a second tty, e.g.:
error_logger:tty({console,tty}).
The same setting can be declared in sys.config:
{error_logger, [{tty,{file,"/var/log/erlang/error.log"}}]}.
Because error_logger is deprecated in OTP 21+, consider using the newer logger module for future‑proofing. If you need guaranteed disk persistence, wrap the file writes in a dedicated process that calls file:write_file/2 with flush or use an external log aggregator.