Repository: Nukesor/pueue (language: rust)

Issue:
[Bug] daemon version warning is written to stdout, not stderr
### Describe the bug

When client and daemon versions differ, all output except for JSON output is prepended with

```
Different daemon version detected '{version}'. Consider restarting the daemon.
```

This message is written to stdout, which means it can't easily be filtered out.

### Steps to reproduce

Run the daemon as version 3.4.0, then use client version 3.4.1 and use `--print-task-id` to only get the task ID to be output:

```
$ pueue add --print-task-id 'echo hello' 2>/dev/null
Different daemon version detected '3.4.0'. Consider restarting the daemon.
1
```

The expected output would be `1`, with `Different daemon version detected '3.4.0'. Consider restarting the daemon.` having been redirected to /dev/null.

### Debug logs (if relevant)

_No response_

### Operating system

Debian 10

### Pueue version

3.4.0 (daemon) and 3.4.1 (client)

### Additional context

At the very least, the message should be written to stderr. Ideally, it should be possible to disable it altogether (`pueue --no-warnings add ...`).


Discussion / hints:
Thinking about it, all logs should probably be sent to stderr and the same should probably be true for `pueued` as well?
> Thinking about it, all logs should probably be sent to stderr and the same should probably be true for `pueued` as well?

Hard to say. Generally speaking, 'out of band' information should go to stderr. When I run `pueue log <TASKID>` the goal is to get the log output of a task, so that should go to stdout. Anything else should go to stderr.
Ah yep. By logs I meant all of the stuff that's printed when `pueue/d` is called with `-v/v/v`

`pueue log` should definitely be put to `stdout`

Fix patch:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 9fcb738f1..e502c0e90 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -43,6 +43,8 @@ TLDR: The new task state representation is more verbose but significantly cleane
   **Important: The Pueue daemon needs to be restarted and the state will be wiped clean.**
 - **Breaking**: Streamlined `pueue log` parameters to behave the same way as `start`, `pause` or `kill`. [#509](https://github.com/Nukesor/pueue/issues/509)
 - **Breaking**: Remove the `--children` commandline flags, that have been deprecated and no longer serve any function since `v3.0.0`.
+- Send log output to `stderr` instead of `stdout` [#562](https://github.com/Nukesor/pueue/issues/562).
+- Change default log level from error to warning [#562](https://github.com/Nukesor/pueue/issues/562).
 
 ### Add
 
@@ -59,6 +61,7 @@ TLDR: The new task state representation is more verbose but significantly cleane
 
 - Fixed delay after sending process related commands from client. [#548](https://github.com/Nukesor/pueue/pull/548)
 - Callback templating arguments were html escaped by accident. [#564](https://github.com/Nukesor/pueue/pull/564)
+- Print incompatible version warning info as a log message instead of plain stdout input, which broke json outputs [#562](https://github.com/Nukesor/pueue/issues/562).
 
 ## \[3.4.1\] - 2024-06-04
 
diff --git a/pueue/src/bin/pueue.rs b/pueue/src/bin/pueue.rs
index ab4b9969c..6fb23a28f 100644
--- a/pueue/src/bin/pueue.rs
+++ b/pueue/src/bin/pueue.rs
@@ -4,7 +4,7 @@ use anyhow::{bail, Context, Result};
 use clap::{CommandFactory, Parser};
 use clap_complete::{generate, generate_to, shells};
 use log::warn;
-use simplelog::{Config, ConfigBuilder, LevelFilter, SimpleLogger};
+use simplelog::{Config, ConfigBuilder, LevelFilter, SimpleLogger, TermLogger, TerminalMode};
 
 use pueue_lib::settings::Settings;
 
@@ -35,10 +35,10 @@ async fn main() -> Result<()> {
 
     // Init the logger and set the verbosity level depending on the `-v` flags.
     let level = match opt.verbose {
-        0 => LevelFilter::Error,
-        1 => LevelFilter::Warn,
-        2 => LevelFilter::Info,
-        _ => LevelFilter::Debug,
+        0 => LevelFilter::Warn,
+        1 => LevelFilter::Info,
+        2 => LevelFilter::Debug,
+        _ => LevelFilter::Trace,
     };
 
     // Try to initialize the logger with the timezone set to the Local time of the machine.
@@ -51,7 +51,17 @@ async fn main() -> Result<()> {
         Ok(builder) => builder.build(),
     };
 
-    SimpleLogger::init(level, logger_config).unwrap();
+    // Init a terminal logger. If this fails for some reason, try fallback to a SimpleLogger
+    if TermLogger::init(
+        level,
+        logger_config.clone(),
+        TerminalMode::Stderr,
+        simplelog::ColorChoice::Auto,
+    )
+    .is_err()
+    {
+        SimpleLogger::init(level, logger_config).unwrap();
+    }
 
     // Try to read settings from the configuration file.
     let (mut settings, config_found) =
diff --git a/pueue/src/bin/pueued.rs b/pueue/src/bin/pueued.rs
index 3313ccacf..6ba11eb72 100644
--- a/pueue/src/bin/pueued.rs
+++ b/pueue/src/bin/pueued.rs
@@ -3,7 +3,7 @@ use std::process::Command;
 use anyhow::Result;
 use clap::Parser;
 use log::warn;
-use simplelog::{Config, ConfigBuilder, LevelFilter, SimpleLogger};
+use simplelog::{Config, ConfigBuilder, LevelFilter, SimpleLogger, TermLogger, TerminalMode};
 
 use pueue::daemon::cli::CliArguments;
 use pueue::daemon::run;
@@ -19,10 +19,10 @@ async fn main() -> Result<()> {
 
     // Set the verbosity level of the logger.
     let level = match opt.verbose {
-        0 => LevelFilter::Error,
-        1 => LevelFilter::Warn,
-        2 => LevelFilter::Info,
-        _ => LevelFilter::Debug,
+        0 => LevelFilter::Warn,
+        1 => LevelFilter::Info,
+        2 => LevelFilter::Debug,
+        _ => LevelFilter::Trace,
     };
 
     // Try to initialize the logger with the timezone set to the Local time of the machine.
@@ -35,7 +35,17 @@ async fn main() -> Result<()> {
         Ok(builder) => builder.build(),
     };
 
-    SimpleLogger::init(level, logger_config).unwrap();
+    // Init a terminal logger. If this fails for some reason, try fallback to a SimpleLogger
+    if TermLogger::init(
+        level,
+        logger_config.clone(),
+        TerminalMode::Stderr,
+        simplelog::ColorChoice::Auto,
+    )
+    .is_err()
+    {
+        SimpleLogger::init(level, logger_config).unwrap();
+    }
 
     run(opt.config, opt.profile, false).await
 }
diff --git a/pueue/src/client/client.rs b/pueue/src/client/client.rs
index cbbe54da5..d67b8c118 100644
--- a/pueue/src/client/client.rs
+++ b/pueue/src/client/client.rs
@@ -5,7 +5,7 @@ use std::{borrow::Cow, collections::HashMap};
 use anyhow::{bail, Context, Result};
 use clap::crate_version;
 use crossterm::tty::IsTty;
-use log::error;
+use log::{error, warn};
 
 use pueue_lib::network::message::*;
 use pueue_lib::network::protocol::*;
@@ -110,7 +110,7 @@ impl Client {
             };
 
             if show_warning {
-                println!(
+                warn!(
                     "Different daemon version detected '{version}'. Consider restarting the daemon."
                 );
             }


Test patch: