Skip to content

enh(logging): add a log_to_file setting so motion can log to stdout - #3394

Open
JamBalaya56562 wants to merge 1 commit into
motioneye-project:devfrom
JamBalaya56562:enh/log-to-file-setting
Open

enh(logging): add a log_to_file setting so motion can log to stdout#3394
JamBalaya56562 wants to merge 1 commit into
motioneye-project:devfrom
JamBalaya56562:enh/log-to-file-setting

Conversation

@JamBalaya56562

Copy link
Copy Markdown
Contributor

Summary

  • add a log_to_file setting to settings.py and motioneye.conf.sample, overridable by the existing -l CLI flag
  • have motionctl honour it: when file logging is off, motion inherits motionEye's own stdout/stderr instead of being redirected to <log_path>/motion.log

Fixes #3330. Implements @MichaIng's outline from #3330 (comment).

Why

motion's output was redirected to <log_path>/motion.log unconditionally, so containerized setups could not see it through docker logs at all. motionEye's own log already goes to stderr by default — only motion's was diverted to a file.

How

  • settings.py / motioneye.conf.sample — new log_to_file setting. The log_path note is on the log_to_file entry, since that is where a reader lands.
  • meyectl.py-l is now resolved in load_settings() next to -d, i.e. after the config file is parsed, so the CLI wins. That makes settings.LOG_TO_FILE the single source of truth, and the five configure_logging() call sites no longer need to pass the flag (shell.py needs no new import).
  • server.py-b still forces file logging, because daemonizing redirects stdout/stderr to /dev/null (Daemon.daemonize()); without this, motion's output would be lost.
  • motionctl.py_get_motion_log_file() returns None when file logging is off, which makes Popen hand motionEye's own stdout/stderr to motion.
  • handlers/log.py/log/motion/ now returns 404 instead of an unhandled FileNotFoundError, since a missing motion.log is the default state after this change.

Default is false — rationale

how it's started args today
extra/motioneye.systemd startserver -c … no -l/-b → motionEye logs to stderr, only motion goes to a file
docker/entrypoint.sh startserver -c … same — this is exactly what #3330 is about
extra/motioneye.sysv startserver -c … -l -b explicitly opts into file logging

So false leaves motionEye's own logging untouched and merely makes motion consistent with it, while sysv users are unaffected. A true default would instead push every systemd user's motionEye log out of journald and into a file, which is the more disruptive change.

Behaviour changes to be aware of

  1. motion.log is no longer written by default. systemd/Docker users get motion's output in journald / docker logs; set log_to_file true to restore the file.
  2. -l can only enable file logging, not disable it (log_to_file true in the config cannot be overridden back to false on the command line). This mirrors how -d relates to log_level, so I kept it consistent — happy to add a --no-log-to-file if you'd prefer it to be symmetric.
  3. Drive-by: removed two leftover sys.stderr.write debug lines in configure_logging() that printed on every single invocation. They're squarely in the way of this PR's goal (clean stdout), but say the word and I'll split them out.

Deliberately out of scope

  • Reducing motion's log level ("I guess we'd need to reduce the motion log level as well") — separate concern, keeping this PR minimal.
  • The pre-existing fd leak in motionctl.start() (log_file is never closed).
  • server.py exiting fatally when LOG_PATH isn't writable — arguably more wrong now that the directory can go unused, but pre-existing.

Validation

  • pytest tests/141 passed (139 before + the new ones); ruff check, ruff format --check, flake8, isort, codespell all clean with the repo's pre-commit args.
  • New tests: tests/test_meyectl.py (config parses log_to_file as a bool, -l overrides it), tests/test_motionctl.py (_get_motion_log_file() returns None vs. an open motion.log), tests/test_handlers/test_log.py (404 when absent, still served when present).
  • E2E against a live server with motion 4.5.1 and a camera configured:
scenario result
default (log_to_file unset) [0:motion] [NTC] … lines appear on motionEye's stdout; no motion.log created ✅
log_to_file true motion.log + motioneye.log written, stdout quiet ✅
-l with log_to_file false both files written — CLI override works ✅
-b with log_to_file false motion.log still written — output not lost to /dev/null
GET /log/motion/ with log_to_file false 404, not a 500 traceback ✅

motion's output was unconditionally redirected to <log_path>/motion.log,
so containerized setups could not see it via 'docker logs' (motioneye-project#3330).

Add a log_to_file setting to settings.py and motioneye.conf.sample, and
have motionctl honour it: when disabled, motion inherits motionEye's own
stdout/stderr instead of being redirected to a file.

The existing -l CLI flag is now resolved in load_settings() alongside -d,
which makes settings.LOG_TO_FILE the single source of truth and lets the
configure_logging() callers drop the flag argument. Daemon mode still
forces file logging, since daemonizing sends stdout/stderr to /dev/null.

Default is false, matching the -l default: systemd and Docker already run
motionEye without -l/-b and get its log on stderr, so this only makes
motion consistent with it. The sysv init script passes -l -b explicitly
and is unaffected.

Also drop two leftover debug writes in configure_logging() that printed to
stderr on every invocation, and guard the log handler against a missing
log file now that its absence is the default.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

1 participant