Skip to content
streamneo.
Troubleshooting15 min read

How to Log FFmpeg Output for a 24/7 YouTube Stream on a VPS

Save useful FFmpeg logs on a VPS and compare them with YouTube Live Control Room health when a 24/7 stream misbehaves.

sn.
StreamNeoPublished 4 October 2026
Worth sharing?

FFmpeg writes its diagnostic output to stderr by default, so a 24/7 stream needs a deliberate way to capture and retain that output. You can use a timestamped diagnostic report for an incident, or route routine stderr output through the VPS process manager or an explicitly managed file.

That local log tells you what the FFmpeg process believes is happening. It does not prove that YouTube is receiving, accepting, or distributing a healthy stream. For that, you must compare the VPS-side record with stream health and messages in YouTube Live Control Room.

Two different kinds of stream evidence

A continuous broadcast has at least two useful viewpoints.

The first is the encoder viewpoint. FFmpeg can report whether it opened the input, decoded frames, encoded video, produced audio, connected to the output, and encountered warnings or errors. It can also show progress and reconnect-related symptoms, depending on the command and the surrounding process setup.

The second is YouTube's ingest viewpoint. Live Control Room can show whether YouTube is receiving the feed correctly and can display stream-health messages with instructions. YouTube says that you can check stream health and analytics while streaming in Live Control Room. Use the official stream metrics guidance for the current interface and terminology.

These views can disagree. FFmpeg may continue reading a looping file and writing data to a network connection while YouTube reports a missing video signal, an unsuitable keyframe interval, or another ingest problem. Conversely, FFmpeg may stop because the input file or local network failed before YouTube has a chance to report much.

A clean-looking local log is therefore evidence about the process, not a certificate that viewers are receiving a good broadcast. When investigating an interruption, note the time in both places and compare what each side was reporting.

This distinction is also useful when deciding what to retain. Routine FFmpeg output helps you identify restarts and recurring warnings. A short Live Control Room capture or written note helps you identify what YouTube saw at the same moment.

Understand FFmpeg's stderr output

FFmpeg's command-line documentation states that, by default, the program logs to stderr. This is separate from the media data sent to your RTMP or RTMPS destination. If you launch FFmpeg in a terminal, you see stderr on screen. If a supervisor launches it, the supervisor may capture that stream, discard it, or send it to its own logging destination.

That behaviour explains why an apparently successful command can leave no log file behind. FFmpeg has not necessarily failed to log. Its output may still be attached to the process's stderr rather than a file in the directory where you looked.

The normal default level is info. You can make the level and timestamps more explicit, for example:

ffmpeg -loglevel level+datetime -i INPUT [encoding options] -f flv 'rtmps://SERVER/APP/STREAM_KEY'

Replace the placeholders with your actual input, encoding options, and destination. Do not paste a real stream key into a public issue, screenshot, article, or support request. YouTube describes stream keys as both the password and address for a live stream, so treat the key as sensitive connection information. The YouTube live stream settings guidance explains how stream URLs and keys fit into the encoder setup.

-stats is enabled by default at the info level and prints encoding progress and statistics. That output is useful for seeing whether frames and time are advancing, but it remains an FFmpeg-side signal. It does not confirm that YouTube has accepted every part of the feed.

For a program-friendly progress stream, FFmpeg also documents -progress URL. That output is intended for software rather than for a human-readable incident diary. You might send it to a local endpoint or file for monitoring, while keeping diagnostic stderr in the service log. Do not confuse progress output with a complete error record.

FFmpeg supports levels including quiet, panic, fatal, error, warning, info, verbose, debug, and trace. A practical arrangement is to keep routine operation at an easily readable level and temporarily increase detail when investigating a particular fault. Permanently enabling debug output can make a long-running log noisier and larger without making ordinary incidents easier to find.

Create a diagnostic report with -report or FFREPORT

For a one-off investigation, -report is the simplest built-in option:

ffmpeg -report -i INPUT [encoding options] -f flv 'rtmps://SERVER/APP/STREAM_KEY'

According to the FFmpeg command-line documentation, -report writes a complete report containing the command line and log output. The filename includes the program name and a timestamp, and the report is created in the current directory. The option also implies debug-level verbosity.

That makes -report useful when a stream will not start, exits unexpectedly, or shows a warning that you cannot reproduce reliably. Before using it on a VPS, check that the current directory is writable and that the account running FFmpeg can read the resulting file. Also check who can access the directory, because command lines and diagnostic output may contain more operational detail than you intend to share.

The extra detail is a trade-off. A debug report can be much noisier than a routine operational log, especially when FFmpeg runs continuously. It is better suited to a controlled diagnostic run or a short period of investigation than to an unexamined permanent setting for a 24/7 channel.

You can configure a report filename and level with the FFREPORT environment variable. The FFmpeg manual gives this form:

FFREPORT='file=ffreport.log:level=32' ffmpeg -i INPUT [encoding options] -f flv 'rtmps://SERVER/APP/STREAM_KEY'

In this example, level 32 is the documented numeric alias for info. FFREPORT uses colon-separated key/value options. If a filename or another value contains special characters or delimiters, follow the escaping rules in the FFmpeg documentation rather than assuming the shell or FFmpeg will interpret them as ordinary text.

A fixed filename is convenient for illustration, but it creates an operational question: what happens when the process runs for days and the file grows? Decide whether the host will rotate, truncate, archive, or replace it. Do not assume that setting FFREPORT automatically supplies retention or rotation.

The manual also notes that errors parsing FFREPORT are not fatal and do not appear in the report. After deploying this pattern, verify that the intended report is actually created and that new entries appear after a restart. A configured variable that was misspelled or quoted incorrectly can otherwise leave you believing that a report exists when FFmpeg is only writing to stderr.

Route output for a long-running VPS process

For a 24/7 service, the durable choice is usually to capture stderr where the process is managed rather than relying on the directory from which someone happened to start FFmpeg. The exact arrangement depends on your distribution, supervisor, hosting image, and service definition.

If your service manager retains standard error, use that destination as the routine record. If it does not, redirect stderr to a file that you have deliberately created, protected, monitored, and rotated. The important point is not the name of the manager. It is that the capture path is known and tested.

A shell redirection illustrates the distinction:

ffmpeg [options] 1>/path/to/normal-output.log 2>/path/to/ffmpeg-errors.log

FFmpeg's diagnostic messages normally arrive on file descriptor 2, which is stderr. Some commands and wrappers also write ordinary progress information there, so the filename ffmpeg-errors.log does not mean every line is an error. Choose a name such as ffmpeg-stderr.log if that is clearer for your team.

You may instead combine standard output and standard error, but separating them makes later diagnosis easier when a wrapper prints its own status messages. Whatever you choose, make sure the target directory already exists, is writable by the service account, and is not on a filesystem that can fill without warning.

After deployment, perform a simple verification rather than trusting the configuration. Start or restart the service, locate the actual destination, and confirm that a new timestamped line appears. Then stop the process in a controlled way and confirm that the final diagnostic messages were retained. Repeat the check after a host restart if the stream is expected to return automatically.

Do not copy a service-manager unit, journal command, or log path from another VPS and assume it is universal. Logging behaviour varies with the host and with whether the process is launched by a system service, container, control panel, cron job, or a shell wrapper. The service's own status page and documentation are the authority for its capture destination.

A VPS is only one way to keep a continuous broadcast running. If your priority is avoiding local power and internet interruptions rather than controlling the process yourself, compare the operational responsibilities in VPS versus a cloud streaming service for a 24/7 lecture channel. The same question applies to devotional channels, ambience stations, and local information loops: who checks the process when the original computer is switched off?

Set retention for managed log files

A log is useful only while it remains available and readable. It also consumes storage, and a continuously running FFmpeg process can produce more output when it is restarted repeatedly or run at a verbose level.

Retention has three separate decisions:

  1. How much history do you need? Keep enough to compare a failure with the events before it, while recognising that the right period depends on how often your channel fails and how much storage the VPS has.
  2. What should happen when a file grows? Rotation may create a new file, compress an older file, or remove old files. The exact behaviour belongs to the tool configured on your host.
  3. Who can read the files? Logs can expose input paths, command-line arguments, network details, and accidental secrets. Keep access narrower than a public web directory.

Do not treat -report, FFREPORT, or stderr redirection as retention systems. They create or route output; they do not establish a universal policy for file size, age, compression, or deletion.

If your host uses a managed logging system, read its current documentation for persistence and retention. Some systems keep recent entries only in memory until you configure persistent storage. Others retain logs on disk but apply host-level limits. The commands and file locations can differ by distribution and by the service manager version, so verify them on the actual VPS rather than using a generic command copied from a forum.

If you manage a plain log file, write down the policy in your deployment notes. Include its path, owner, rotation method, maximum storage you are willing to allocate, and the check that confirms rotation occurred. Test the policy with a harmless temporary log or during a planned maintenance window. A policy that has never been observed rotating is only an assumption.

Avoid deleting the only copy immediately after a fault. Before cleanup, preserve the relevant period and record the approximate UTC time of the incident. If you send a report to someone else, remove or redact the stream key and any other sensitive values first.

For a stream built from prerecorded files, logging is only one part of keeping the channel dependable. Input loops, network use, and unnecessary re-encoding also affect the process. The guide on reducing electricity use when streaming prerecorded videos on YouTube 24/7 covers the operational choices around a continuous file-based stream.

Compare local logs with YouTube Live Control Room health

When FFmpeg reports that it is encoding and sending data, open Live Control Room and check the destination-side status at the same time. YouTube's encoder settings guidance covers current protocol, codec, bitrate, frame-rate, and keyframe considerations. Its guidance recommends RTMP or RTMPS, constant bitrate encoding, and a two-second keyframe interval that should not exceed four seconds. Use the official bitrate table for your codec, resolution, and frame rate rather than applying one number to every stream.

A useful incident timeline has four entries:

Time VPS-side evidence YouTube-side evidence Working conclusion
Before the fault FFmpeg input, frame, and audio progress Healthy stream status Process and ingest were aligned at this point
At the fault Error, stalled timestamps, reconnect, or process exit Health warning or loss of signal Compare the first change rather than the last message
During recovery New process start and advancing progress Health returns or remains degraded Shows whether restart restored the feed
After recovery Stable output and expected input loop Stable metrics and viewer-facing video Both viewpoints now agree, if they do agree

The exact messages matter. A local Broken pipe, connection failure, or input read error points you towards the process, input, or network path. A healthy local encoder combined with a YouTube warning points you towards ingest settings, keyframes, bitrate, codec compatibility, or another destination-side issue. These are directions for investigation, not proof of a single cause.

YouTube recommends testing a stream and monitoring stream health while it is operating. If you change encoding settings, make one controlled change at a time and note the result in your incident record. This is more useful than replacing a working command with several new variables at once.

Do not assume that a 24-hour plan will be archived under the same condition as a shorter stream. YouTube's encoder setup guidance says that streams under 12 hours are automatically archived. A planned 24/7 broadcast should not rely on that statement as a promise that one uninterrupted 24-hour event will be archived in the same way.

If you are unsure whether the stop came from FFmpeg or the network, use the timeline method in how to tell whether a YouTube live stream stopped because of the encoder or internet. It complements the logs rather than replacing the Live Control Room check.

Troubleshoot missing or unhelpful output

There is no file where you expected one

First identify how FFmpeg was started. If it was launched interactively, its output may still be in the terminal. If it was launched by a service, inspect that service's documented stdout and stderr destination. If you used FFREPORT, verify the variable reached the FFmpeg process and check the process's current working directory.

Also check permissions and disk space. A report directory that is not writable, or a filesystem that is full, can prevent the record you expected. Make a controlled restart and confirm that the chosen destination receives fresh output.

The log contains only a few lines

The process may have exited before it reached the part of the command you are investigating. The wrapper may also be capturing stderr somewhere else, or a quiet log level may be hiding routine detail. For a repeatable failure, run a short diagnostic test with -report, confirm the report path, and remove or protect the resulting file when finished.

The log is too large or too noisy

Check whether -report is still enabled. It implies debug verbosity, which can be excessive for routine 24/7 operation. Return to a readable level for normal service operation, then use a temporary detailed report when investigating a specific event. Review the host's actual rotation and retention behaviour rather than deleting files manually without preserving the incident period.

The log looks healthy but viewers report a problem

That is the expected reason to check two sources. FFmpeg can show advancing local encoding while YouTube reports a health issue, or while a viewer-facing problem is caused by a setting the local process cannot validate. Compare timestamps, inspect Live Control Room messages, and check the official encoder guidance before changing the command.

The report exposes the stream key

Treat the key as compromised if it has been shared where others can read it. Remove it from screenshots, shell history where practical, tickets, and copied commands. YouTube's guidance explains that the key is the information used to direct the encoder to the stream and allow YouTube to accept it, so protect it like a credential.

A practical operating routine

Before going live, confirm that the input file is readable, the output destination is correct, the service account can write the intended log, and the log destination has available space. Start with routine verbosity and keep a note of the command version and the time the process began. Never include the real stream key in that note.

During normal operation, check that timestamps or progress continue to advance, but do not use that alone as a health check. Open Live Control Room and confirm the destination-side status. For a channel that runs overnight, arrange a simple morning check of both the VPS record and the YouTube status rather than assuming that an unchanged process means an unchanged broadcast.

When something fails, preserve the relevant local log before rotation removes it. Record the UTC time, the last useful FFmpeg message, the process state, and the Live Control Room message. If the cause is still unclear, run a temporary -report capture during reproduction rather than leaving debug mode enabled indefinitely.

StreamNeo removes the need to maintain this VPS-side FFmpeg logging path when your requirement is simply to upload a prepared video, provide the YouTube stream key, and have the channel run with monitoring and automatic restarts while your computer is off.

If you are still building the command, compare it with the best FFmpeg settings for looping educational videos on YouTube Live, then verify the resulting stream in Live Control Room rather than relying on the local log alone.

Before committing, compare the operating options on the pricing page. When the file and channel are ready, start free — 24-hour trial, no card.

FAQ

Where does FFmpeg write its logs by default?

FFmpeg writes diagnostic output to stderr by default. In a terminal, that usually means the screen; under a service manager, it depends on how the service captures standard error. Use -report, FFREPORT, or the host's configured stderr destination when you need a durable record.

Does a successful FFmpeg log prove that YouTube is receiving a healthy stream?

No. It shows what the local process is doing, such as reading input and producing output, but it cannot by itself validate YouTube's ingest or viewer-facing health. Check the stream status and messages in Live Control Room alongside the VPS log.

Should -report remain enabled for a 24/7 stream?

Usually, treat -report as a diagnostic tool because it implies debug-level verbosity and can create noisier output. For routine operation, use a readable level and a host-managed capture path, then enable a detailed report for a controlled investigation. Confirm that your chosen retention method can handle the resulting files.

Are service-manager and retention commands the same on every VPS?

No. Log persistence, destinations, rotation, and retention depend on the distribution, service manager, hosting image, and deployment method. Read the documentation for the actual host, verify the path after a restart, and test that old logs are handled as intended.

YOU’VE REACHED THE END

Keep the ideas coming.

More guides, useful tools and a little help for your next broadcast.

Back to the journal ↗
YOUR NEXT READ

A little more to explore.

More Troubleshooting guides ↗ · All topics ↗