Repository navigation
rtapi: end every message that lacks the newline - #4697
grandixximo wants to merge 4 commits into
Conversation
|
It is probably a good thing to enforce a newline but it can have side effects. A few things to consider: linuxcnc/src/emc/motion/homing.c Line 282 in eab7726 The _( including #define _(s) (s) can probably be removed as long as homing.c is only used in realtime context.
There are some places like this: linuxcnc/src/emc/motion/command.c Line 2136 in b99baf8 linuxcnc/src/rtapi/uspace_rtapi_app.cc Line 252 in b99baf8 This cases will now produce to many newlines or clobbered messages. As soon as motion is running, messages go trough a different path: linuxcnc/src/emc/motion/motion.c Line 460 in b99baf8 linuxcnc/src/emc/motion/motion.c Line 247 in b99baf8 As much as I remember, this path to the gui goes to translation and adds a newline always. That's why the GUI pop-up's often have a newline to much. But a lot was changed since I touched it in #4116. |
|
@hdiethelm thanks for looking. In order:
|
|
@hdiethelm, does the reply above settle your points? If so, I would merge this. |
|
I need to think a bit more about this. Adding only newlines if missing and only if error or warning is not consistent and will make future bugs more likely. One might set an info message to error temporarely to test something and then wonders why it behaves differently. Then he will fix it not realizing that this is now wrong for info. Also errors go to the GUI where a newline is added unconditionally as much as I remember. So it would be better to add a newline always and fix all the messages. But this is a lot of change. Or just leave it for now, there are discussions going on about a logging system, and continue as soon they have setteled. |
|
So, I was able to verify my suspicion: Checking other places for logs, it's a mixed bag: What I would suggest:
Now this would be quite a change to remove several 1000's of trailing newlines in code. However, it would clear the way to use a logging library and make things consistent. The few places where one message is created using multiple @BsAtHome Some input from your side? |
|
Just a quick&dirty spdlog prototype: https://github.com/hdiethelm/linuxcnc-fork/tree/spdlog_prototype |
Every rtapi_print_msg() message is a line of its own: the uspace default handlers, in the main thread of rtapi_app, in the queue that prints the messages of its realtime threads and in user processes, add the newline when the text lacks one, at every level. rtapi_print() still prints like printf. A message that already ends in a newline does not change, so the existing formats and their translations stay as they are, and new code may leave the newline out. tests/rtapi-msg-newline prints errors, a warning and an info message without a newline from the main thread of rtapi_app and from a realtime thread, an error with its newline, and an rtapi_print() line in two parts. Fixes LinuxCNC#4689.
|
@hdiethelm, I agree the split between errors and warnings and the other levels is the weak point, and your screenshot shows a second bug on the GUI side. Here is a middle step that I think gets your rule without the big sweep:
For scale, a scan of Tested with a component that prints one error without and one with the newline, loaded into the axis sim: on master the console shows The RTAI kernel handler is unchanged. The three commits are on msg-one-line. @BsAtHome, this is your fix at the endpoint, extended to every level. If you both agree, I will put them on this PR in place of the current commit. |
I prefer msg-one-line. It is more a step in the right direction instead of a workaround. RTAI uses linuxcnc/src/rtapi/rtai_rtapi.c Line 439 in 062dc7c linuxcnc/src/rtapi/rtai_ulapi.c Line 273 in 062dc7c |
|
Have you tested with the Touchy GUI? That has a single line status bar at the bottom of the screen. (As an aside, Touchy really could do with a way to view multi-line and multiple errors, at the moment you only see the last line of the last error. The obvious place would be a field in the status tab) |
|
First, there may be differences in how debug messages or non-debug messages are constructed. The debug messages are for the console. A GUI has no space or time to handle the flood. An example is: linuxcnc/src/hal/drivers/mesa-hostmot2/hm2_modbus.c Lines 497 to 501 in 062dc7c It calls rtapi_print_msg() multiple time without newline and then terminates the line manually. Therefore, adding newlines automatically cannot be done for debugging. For errors and warnings it is probably alright because these messages are routed to the GUI, which cannot construct partial messages into one whole.
Second, all the Third, when we are to define new logging, then I'd suggest we start thinking about more fine-grained control over informational and debug messages. You want to have a "channel" that identifies a part of the code and can be switched on/off. That reduces the clutter when trying to find something specific. Fourth, logging is generally a mess and inconsistent. We need to unify both the messages' content and the way they are routed. Much of the user-space just routes to stdout/stderr without thought. Fifth, placing log message in the code is not done consistently. We need to have a review of info/warn/error messages. When do we want to have a log message for what information including which content. That is a difficult one, but needs an answer. Then it needs to be implemented. |
|
@BsAtHome, on the first point: #ifdef DEBUG
char hex[3 * MAX_PKT_LEN + 1];
MSG_DBG("Sending cmd=%u to '%s' %i bytes:%s\n", inst->cmdidx, inst->uart, cc->datalen,
hexdump(hex, sizeof(hex), cc->data, cc->datalen));
#endifA line built in parts is a set of separate messages, so whatever another thread or process prints between them lands in the middle of the line; in uspace each part of a realtime message is its own entry in the queue. One call per line keeps the line whole at any level. There were six such places in the tree, and the second commit changes them all. If you still want debug to stay printf-like, I can give the newline to error, warning and info only and leave debug as it is; @hdiethelm, would that work for you? The formats stay printf formats; the handler only adds the newline after formatting. Agreed on the rest: channels, routing and a review of what we log belong to the new logging work, and this does not get in its way. @andypugh, yes. Touchy's error line is a single-line label, so a newline never hides the text: GTK draws it in place as a @hdiethelm, I added the two RTAI places in a fourth commit: the kernel handler ends a message that lacks the newline before |
The RTAI kernel handler and rtapi_print_msg() in RTAI user space follow the same rule as uspace: every rtapi_print_msg() message is a line, and rtapi_print() prints like printf. printk() shows a message without the newline only when the next one comes. The kernel handler now gives rt_printk() the text as an argument instead of as the format. Hannes Diethelm pointed out both on LinuxCNC#4697.
Indeed, there are many places you might miss due to they use defines like in this case. Never the less, one message should be one message and this should be fixed in my opinion. Having different ways messages should be constructed depending on the severity level is inconsistent and bug prone. Doing the example above with //bad
printk(KERN_INFO "Hello, ");
printk(KERN_INFO "world 1\n");
//good
printk(KERN_INFO "Hello, world 2\n");
printk(KERN_INFO "Hello,\nworld 3\n");->
In turn, this would mean a newline should be added here and drop this PR: linuxcnc/src/emc/motion/homing.c Line 282 in eab7726 But it does not have to be, you can add the newline just before
Agreed. The way it is right now, it is often easier to just redefine a message to ERR temporarily instead of dealing with the flood of debug messages.
Also agreed. Using ERR for info messages which are important for the user to see just due to there is no other option is fully inconsistent. For many messages, it is unclear if it is an issue or just a don't care. I had a hard time figuring out the reason for a test fail due to this. You got 100's of messages. Most are info or warning but one is a hard fail. No way to see which one. Normally, the default log level where your are not spawned with 1000's of debug messages should be info, might be warn. But for sure not error. |
|
@grandixximo Our responses just crossed. Yes, an additional issue with using multiple messages to create one is the race conditions it will generate. Anyone not wanting to use temporary strings for quick debug messages during development can still use
Looks good in the code. Tag me when the discussion has settled and I will test it. The RTAI VM is a bit cumbersome, it has fixed screen resolution, no copy paste from host, crashes from time to time and so on. |
|
Right, split debug messages need fixing. Not really nice with the static buffer, though, especially not nice because it is on the RT thread's stack (compiler may generate frame size problems). These debug message will get split in the kernel (not often used), but on the console they generally do not. But, yes, it is a race which message comes first when multiple threads are competing (not likely with mostly only one RT thread). We also need to separate the RT messages from the non-RT message. It is often a messy business. RT needs to use About channels, has anyone ever looked at Wine? They have a channelized message system that is rather fine-grained. Especially helpful with separating the DLLs' messages and allows only showing what you really need. Could be inspirational. |
Now that every message is a line, the places that built one line from several calls print it with one: motion's command debug output, rtapi_app's isolated cpuset report, the PPMC slot scan, halcmd's command echo and the hm2_modbus frame dumps. Hannes Diethelm listed most of them on LinuxCNC#4697.
An operator error is one line, and the GUIs and task's echo end it, so task drops the newline at the end of the text; motion's errors that end in one showed a blank line in every GUI. reportError() likewise adds its newline for the console only when the text lacks one.
The RTAI kernel handler and rtapi_print_msg() in RTAI user space follow the same rule as uspace: every rtapi_print_msg() message is a line, and rtapi_print() prints like printf. printk() shows a message without the newline only when the next one comes. The kernel handler now gives rt_printk() the text as an argument instead of as the format. Hannes Diethelm pointed out both on LinuxCNC#4697.
a81fd9f to
de21b0b
Compare
|
@BsAtHome, good catch on the stack. The dump buffer was // Debug dump of a frame, one message for every 16 bytes
static void dump_frame(const char *what, unsigned cmdidx, const rtapi_u8 *data, unsigned len)
{
for(unsigned i = 0; i < len; i += 16) {
char hex[16 * 3 + 1] = "";
unsigned n = 0;
for(unsigned j = i; j < len && j < i + 16; j++)
n += rtapi_snprintf(hex + n, sizeof(hex) - n, " %02x", data[j]);
MSG_DBG("%s cmd=%u [%u]:%s\n", what, cmdidx, i, hex);
}
}Agreed on splitting the RT messages from the rest, with I moved the four commits onto this PR and updated its description. I think at least the shape of this PR is settled; whatever comes next, we will see. @hdiethelm, it is ready for the RTAI run when you have time. |
Please dont use rcs_print, use https://github.com/LinuxCNC/linuxcnc/blob/master/src/emc/logutil.hh#L37 |
|
Well, I objected to prematurely changing the logging infrastructure. Logutil is just a half fix of the old system without actually fixing the real problem IMO. |
FWIW, if it has been replaced, why is it still present in the code and why is it still in libnml? Just changing logging by renaming (and using libfmt) does not set the stage for the real changes necessary IMO. |
|
@grandixximo So it looks your code works, just other issues. Like every time I test RTAI for a change... ;-) RTAI also does not suport changing log level, so only errors are shown.
|
its still in the code because libnml uses it internally, and there is no point in converting libnml as it will be removed anyway. It does set the stage, as there is now one place to implement the new system.
Well, I also objected to your hal changes ;D There wasnt much of infrastructure, there was broken code. So far I have received Zero productive input on logging, So Im working on spdlog. Please continue the discussion in the logging discussion #4638 if you have Ideas. |
I find this type of "jokes" very offensive (seriously). |

Fixes #4689. @BsAtHome, this is your idea of fixing it where the message is printed, extended to every level. @hdiethelm, thanks for the report and for pushing it this way.
Every
rtapi_print_msg()message is a line of its own:rtapi_print()still prints like printf. A format that already ends in a newline prints as before, so the existing formats and their translations do not change, and new code may leave the newline out.↵glyph. Motion'sreportError()adds its console newline only when the text lacks one.rt_printk()the text as an argument instead of as the format.tests/rtapi-msg-newlineprints errors, a warning and an info message without a newline from the main thread of rtapi_app and from a realtime thread, an error with its newline, and anrtapi_print()line in two parts. I also checked the errors Touchy shows, from a test component and from task and motion, on master and with this PR: the only difference is the glyph at the end. The full suite passes apart from blendmath, which does not build with GCC 14 (#4676). I cannot build RTAI here.