Output levels

A place to discuss everything about the Orxonox framework.

Moderator: PPS-Leaders

User avatar
x3n
Baron Vladimir Harkonnen
Posts: 810
Joined: Mon Oct 30, 2006 5:40 pm
Contact:

Output levels

Post by x3n » Wed Jun 15, 2011 9:13 am

Before our (maybe) upcoming release I want to improve the output in the logfile to get logs which are actually useful to debug. I think this is a good opportunity to talk about the different output levels (errors, warnings, etc) and some guidelines about how to use them.


Output levels:
In my opinion we should make a difference between messages which are important for the user (player) and messages which are important for the developers. User related messages are shown in the console while developer related messages are only written to the logfile. Additionally we may need some extra verbose output if we're about to debug a specific part of the application (e.g. level loading, network, notifications, etc).

This leaves us which 3 major output levels: normal (user), internal, and verbose.
  • normal output is visible in the console and the logfile
  • internal output is visible in the logfile
  • verbose output is visible in the logfile only when requested (through a config value)
Additionally there are 4 minor output levels for both normal and internal output:
  • status: a notification about the current state of the application
  • error: there was an unrecoverable error
  • warning: there was a recoverable error
  • info: some progress information of little importance
In combination we have the following output levels:
  • user status
  • user error
  • user warning
  • user info
  • internal status
  • internal error
  • internal warning
  • internal info
  • verbose
  • (verbose++)
For verbose output we define different "contexts" instead of levels. For example verbose output in the context of XML loading, network, notifications, class hierarchy, input, etc. Output for each context can be enabled individually.


Guidelines:
Here are my guidelines how to use the different output levels:

Amount of output:
  • output with user level should be very limited and actually important for the user. Target: A few dozen lines in the console after playing some levels (~10 lines for startup, ~5 per level)
  • output with internal level should be helpful for debugging. Target: a few hundred lines in the logfile after playing some levels (~100 lines for startup, ~50 per level)
Frequency of output:
  • output with user level is used to directly communicate with the user. It should not be repeated. For example, if the initialization of openAL fails, we print one error. But we don't print an error each time we try to load a sound source.
  • There's no need to print 20 lines to the console within 1 second. The target is to not exceed 1 line per second (unless the user manages to change the application's state more frequently by clicking lots of buttons).
  • if an action takes more than 1 second to process (e.g. level loading), some intermediate progress information can be printed with user info level.
User <-> Internal:
  • Both major output levels (user, internal) have 4 minor sub-levels (status, error, warning, info). The difference is that internal output is more fine grained than user output.
  • If the user clicks a button there should be at most 1 state change at user level. However this state change may require 10 internal state changes
  • User notifications should only contain stuff the user knows. He should know what a level file is, but he doesn't have to know that it contains XML. As a result, print a user error if the level file doesn't exist, but only an internal error if the XML code is malformed
Status <-> Info:
  • output with user status level should inform the user about the state of the application (e.g. application started, loosely related to gamestates).
  • output with internal status level should give us some information in which state the application was before it crashed.
  • output with info level can be used to print some intermediate information between two states.
Error <-> Warning:
  • error level is for unrecoverable errors: the application has to go back to the old state (or to another known state, e.g. mainmenu). It's not possible to have 2 consecutive errors (theoretically).
  • warnings are for recoverable errors. There can be multiple warnings at the same time, but to meet the "Frequency of output" guidelines, several warnings of the same type should be summarized (and yes, this means some work)
Of course there's some tolerance. For example, the levels user info and internal status are more or less equally important/frequent, but it's up to the programmer to decide whether or not some output is important for the user while playing the game. The same holds for the internal info and verbose levels.

Also the border between errors and warnings is blurred: In general, error messages are for unrecoverable errors when the requested operation can not be completed. Warnings are for recoverable errors. However it's possible that something which triggers an internal error is at the same time also a user warning, for example during level loading when some object could not be created (internal error in the factory), but the loader recovers from this error and prints only a warning to the user.

Some more points:
  • No output in tick(), it simply becomes too much and is probably not helpful
  • Chat and kill-messages should not be treated as output, more like notifications

Examples:
Here are some examples in the context of level loading. Note that, as stated above, the difference between user info and internal status, as well as internal info and verbose is not clearly defined. It depends on how useful the information actually is and if we can adhere to the "Amount of output" guidelines.
  • user status:
    status: Loading level tutorial.oxw...
    status: Finished loading
  • user error:
    error: File "tutorial2.oxw" does not exist
  • user warning:
    warning: Could not find mesh "debris.mesh"
    warning: 3 object(s) could not be loaded
  • user info:
    info: Loading templates...
    info: Loading objects...
    info: Preloading meshes...
    info: Preloading materials...
    info: Player entered the game
  • internal status:
    status (internal): Opened level file "tutorial.oxw"
    status (internal): Parsing XML...
    status (internal): Processing Lua...
  • internal error:
    error (internal): Preloading: File "debris.mesh" does not exist (in object of type "Model" loaded from tutorial.oxw line 208)
    error (internal): Class "SpaceShiiip" does not exist (tutorial.oxw line 54)
  • internal warning:
    warning (internal): Could not convert string "hello world" to float
    warning (internal): Found unknown XML attribute "orientationnnn" in object of type "Model" (tutorial.oxw line 208)
  • internal info:
    info (internal): Created instance of class "Model"
    info (internal): Preloading "debris.mesh"...
  • verbose:
    verbose (loader): Loading XML attribute "position": string "1,2,3" converted to Vector3(1, 2, 3)
    verbose (loader): Loading XML attribute "scale": string "hello world" converted to float 0.0000
Fabian 'x3n' Landau, Orxonox developer

User avatar
x3n
Baron Vladimir Harkonnen
Posts: 810
Joined: Mon Oct 30, 2006 5:40 pm
Contact:

Re: Output levels

Post by x3n » Wed Jun 15, 2011 12:15 pm

While thinking about it I get the impression that we should change the definition of the importance of the different output levels even more. I would prefer this order:
  • 0: user error
  • 1: user warning
  • 2: user status
  • 3: user info
  • 4: internal error
  • 5: internal warning
  • 6: internal status
  • 7: internal info
  • 8: verbose
  • 9: (verbose++)
Higher level means less important.

Because honestly, I think an error is more important than a silly "level loaded" status notification.
Additionally this order gives us the possibility to increase the output level for the console for developers to 5 (internal warning). This way developers see both kinds of errors and warnings (user and internal) in the console, but the less important internal status is still only visible in the logfile.

Of course this practically disables the quite popular use of COUT(0) (which formerly was equivalent to user status, but with the new ordering is defined as user error). However we still have the possibility to use COUT(-1) which makes the intent of forcing output to the console even more obvious. Of course this should only be used for debugging purposes. iirc reto added a DOUT macro in his branch for exactly this purpose.
Fabian 'x3n' Landau, Orxonox developer

User avatar
Mozork
Mogthorgar, the mighty
Posts: 134
Joined: Wed Sep 24, 2008 3:27 pm

Re: Output levels

Post by Mozork » Wed Jun 15, 2011 5:40 pm

This sounds like a useful thing to have! Although it might require quite some effort to port all the log messages to it.

I'm curious how would the verbose contexts be defined, both when printing a log message and when deciding what you want to be displayed? Maybe a own makro VOUT("context")?

Additionally: I think it might be useful to be able to display messages up to say output level 5 plus additionally all the verbose loader messages.

User avatar
1337
Baron Vladimir Harkonnen
Posts: 521
Joined: Wed Oct 10, 2007 7:59 am

Re: Output levels

Post by 1337 » Wed Jun 15, 2011 7:18 pm

Without reading the post: I've given it quite a bit of thought myself recently because I wasn't satisfied with the current system. So I'm glad someone actually gives it some real thought.
I'll comment on it later after work.

In the meantime, I have a creativity exercise for all of you:
Creative ways to find software bugs
http://www.xkcd.com/
A webcomic of romance, sarcasm, math, and language.

User avatar
x3n
Baron Vladimir Harkonnen
Posts: 810
Joined: Mon Oct 30, 2006 5:40 pm
Contact:

Re: Output levels

Post by x3n » Wed Jun 15, 2011 7:30 pm

I tend to encode the context in the output level - for example the lower 8 bits define the output level as a number (possible values 0-255 or -128-127) and the upper 24 bits form a bitmask where each bit stands for a context.

contexts can be defined like this:

Code: Select all

CONTEXT_LOADER        = 0x00000100
CONTEXT_NETWORK       = 0x00000200
CONTEXT_NOTIFICATIONS = 0x00000400
printing output works like this:

Code: Select all

COUT(VERBOSE | CONTEXT_LOADER) << message
the output you want to see can be defined like this:

Code: Select all

PRINT_LEVEL = 5
PRINT_CONTEXTS = CONTEXT_LOADER | CONTEXT_NOTIFICATIONS
the decision in the output handler looks like this:

Code: Select all

if (level & 0x000000FF <= PRINT_LEVEL || level & PRINT_CONTEXTS)
    print(message)
That's just one possibility of course, but probably one of the most efficient approaches. Using strings would work as well, is way more flexible, and would be easier to define as a config value, but it's much slower and there's no compile time verification of the output context (i.e. if you misspell it)
Fabian 'x3n' Landau, Orxonox developer

User avatar
Mozork
Mogthorgar, the mighty
Posts: 134
Joined: Wed Sep 24, 2008 3:27 pm

Re: Output levels

Post by Mozork » Wed Jun 15, 2011 7:59 pm

The question is whether we need the speed. 24 bits (i.e. 24 different contexts) sounds quite limiting to me.

On the other hand it really is fast and I love the simplicity, so we could probably create a dedicated type where we use int32 for now and can easily extend it if we need more contexts.

User avatar
x3n
Baron Vladimir Harkonnen
Posts: 810
Joined: Mon Oct 30, 2006 5:40 pm
Contact:

Re: Output levels

Post by x3n » Wed Jun 15, 2011 10:09 pm

yeah true it's limited, but I think the possible contexts are also more or less limited, because it's mainly used in the different parts of the framework. But if this is really an issue, we could implement it differently. However I'm not sure how big the performance penalty would be if you have to make a lookup in a set for a string for every possible output in the code...
Fabian 'x3n' Landau, Orxonox developer

User avatar
1337
Baron Vladimir Harkonnen
Posts: 521
Joined: Wed Oct 10, 2007 7:59 am

Re: Output levels

Post by 1337 » Fri Jun 17, 2011 10:04 pm

Sorry for the late answer, but here it is.

First, I would simply like to share what I think the shortcomings of the current system are.
  1. I definitely miss the context specific stuff. So it would be nice to know the context of a log entry, but it would also be nice if we could boost the priority of a specific context for improved debugging.
  2. Sometimes I feel like we mix up log entries and notifications because of priority and addressee issues.
  3. Logging cannot be used among different threads
  4. Logging doesn't doesn't catch stuff printed to stderr and stdout, for instance be ENet
  5. I don't like the log levels very much the way they are because 0, 1&2 and 3-6 are quite different kettle of fish. The overall priority makes sense though.
For our Gruppenarbeit project I also wanted to log, but it had to be thread safe, so I chose a log function instead of streaming operators to distinguish individual entries. It looked like this then:

Code: Select all

TRACKER_LOG("Some value: " << myValue << ".");
The implementation is pretty ugly and it's probably not very fast because it has to construct a temporary std::ostringstream for every entry. But that didn't matter. We could use this for Exceptions though (might have already implemented that in Orxonox, don't remember).
Anyway, I prefer our approach. It's simpler and more intuitive when you're used to std::cout.
Also, I experimented with different log types: Assertion, Exception, Warning and Info. And each type was allowed three levels: High, Normal and Low.
But it turned into a mess because it wasn't always clear how exactly I should order them in terms of priority.
I also used different macros (TRACKE_INFO, TRACKER_WARNING, TRACKER_EXCEPTION and TRACKER_ASSERT) for each purpose.
Furthermore, the log file was structured pretty much like cegui.log, so each entry had multiple attributes like time, importance and message.

So much about my previous experience with logging.
Now, in Orxonox we have of course different requirements.
Nevertheless I think it would be a very good idea to have different keywords. Fabian, you suggested to differentiate between and developer messages. This is different from what I suggested because. That raises the question: What should the log message define, the addressee or the origin? So does it say whether it's for the user or the developer or does it say what it is or even both?
Also, what exactly is the user? I understand that the normal gamer never even opens the console, so anyone doing that is either a power gamer or a developer. Then it seems to be difficult to draw the line.

@Multithreading: I'm not entirely sure how important this is, but not being able to log anything in another thread seems like a pretty severe limitation to me. I have a solution for that though. I have seen this idiom in another Qt project: usage exactly like our COUT, but the message only gets written AFTER everything has been pushed into it. The way to do this is to have COUT construct a temporary object that acts like an std::ostringstream and then write everything to the output in the destructor of that temporary object.
There might be a performance issue though: I measure something around 100 microseconds to construct an std::ostringstream. That's too much in my opinion. But we could of course reuse them.
Alternatively, COUT could just lock the OutputHandler with a mutex and then unlock it again in the destructor (again with that temporary object).
That actually sounds much simpler ^^

So, this has not been very constructive in general. But it might serve as an additional source of ideas. Maybe I can work something out later. But I would like to hear your opinion first.

One more thing: Before creating any output branch, we should test and merge unity_build because I added a debug macro. But I see that you already caught this.
http://www.xkcd.com/
A webcomic of romance, sarcasm, math, and language.

User avatar
x3n
Baron Vladimir Harkonnen
Posts: 810
Joined: Mon Oct 30, 2006 5:40 pm
Contact:

Re: Output levels

Post by x3n » Sat Jun 18, 2011 1:31 pm

Logging cannot be used among different threads
Logging doesn't doesn't catch stuff printed to stderr and stdout, for instance be ENet
True, however I'm currently not so much interested in improving our logging functionality, but rather the log output itself. As you know we want to make a small beta release soon and right now we couldn't help users at all if they report an error because except for the backtrace after a crash we have no meaningful output. So my goal is to create output which is actually useful. To do that, it makes sense to re-think some design decisions related to the COUT macro and the output priorities. The result of this re-thinking is written down in this thread and unless someone expresses concerns I'll implement it like that because it doesn't require significant changes in the framework and if necessary it could be changed again in the future without much pain (e.g. if we decide to use strings for contexts instead of bitmasks).

Indeed thread safety and other features would be nice to have, but for the moment I'd like to adhere to our (inofficial) feature freeze and just polish the game wherever it is necessary.
I don't like the log levels very much the way they are because 0, 1&2 and 3-6 are quite different kettle of fish. The overall priority makes sense though.
If I get this right, your concern is that incrementing the output level by 1 doesn't give you the same output with less priority, but instead a completely different meaning of the output, right?

Indeed this is also one of my concerns. First of all I adressed this with the new output levels which make clear that the priority is not mainly defined by the discrimination between error, warning, status, and info levels, but rather by the user, internal, and verbose level-groups.
Second, as you can see in my example, I'd like to use named constants instead of magic number. This requires a bit more typing, but considering that each and every line of output should be well thought out, this is no big deal.
Fabian, you suggested to differentiate between and developer messages. This is different from what I suggested because.
What?
That raises the question: What should the log message define, the addressee or the origin? So does it say whether it's for the user or the developer or does it say what it is or even both?
Very good question. In my approach, the user/internal levels define the addressee, while the error/warning/status/info levels define the type of the message.

Maybe at the first glance this looks confusing, but I'm pretty confident it makes sense because that's more or less the way we communicate in real life.

For example, consider a restaurant. There's a big hurry in the kitchen and at some point a cook makes a mistake, he drops too much salt into the soup and it gets uneatable. At first the cook is very miserable about it, explains his colleague in detail how this happened: his hand was numb after carrying a bucket of ice cream (this is verbose output). Then he walks over to his boss and explains that the soup is uneatable, whereon the boss responds that he has to make a new soup (internal output). Now of course the guests are waiting, so the waiter has to tell them that "we're sorry but it takes a bit longer because the kitchen is very busy at the moment" (user output).

As you can see, those 3 major output levels differ in the amount of details and abstraction. User, internal, and verbose levels each have a different addressee.

Of course also the minor output levels exist in real life, for example if the waiter announces the band, he may do so with normal voice (info level). But if the kitchen is on fire, he'll definitely raise his voice (error level). You can also imagine that if someone says something with high importance he will always interrupt people talking about stuff with lower importance.

From this example it gets clear that the 4 minor output levels define the importance or priority of the message.

Also, what exactly is the user? I understand that the normal gamer never even opens the console, so anyone doing that is either a power gamer or a developer. Then it seems to be difficult to draw the line.
That's true, I guess we'll have to add some "real" error notifications (e.g. a popup) in the future, but right now that's not really important. Most of our current users are PPS students, level creators, content designers. They will test stuff and if it doesn't work they'll look at the output. It makes sense to show them some concise information.

Also if we build an editor, we can add a window to list errors and warnings, much like compiler output in an IDE.

So the "line" between users and developers is indeed very blurred, but I think the user output is more for the (non technical) content developers, while internal output is more for coders. Power gamers are on the same level as content developers because they have to know the game to quite some extent, so they know the console. And casual gamers should never experience an error anyway because we can assume that we release the game in a tested and stable form, so it's not possible to have a malformed XML file or a missing mesh.

Also think about the main reasons to show a user error:
a) Something goes wrong during startup (can't initialize graphics or sound): The user will see the error because at this point only the console is visible.
b) Something is wrong with a level file or other content (mesh, texture, etc): This happens only if you create or modify levels, so the console is part of your toolchain.
c) You enter a wrong command: Happens only if you open the console (or modify the keybindings), so you obviously see the console (or you're a power user).
Fabian 'x3n' Landau, Orxonox developer

User avatar
1337
Baron Vladimir Harkonnen
Posts: 521
Joined: Wed Oct 10, 2007 7:59 am

Re: Output levels

Post by 1337 » Sun Jun 19, 2011 3:25 pm

Thank you very much for taking the time to consider my thoughts. I see your points, especially the one about improving the output, not the logging system.

Forget about the incomplete sentence, I should have deleted it anyway, because I rewrote it and you answered to that ;)
x3n wrote: a) Something goes wrong during startup (can't initialize graphics or sound): The user will see the error because at this point only the console is visible.
That makes me recall that I wanted to reconsider a decision I made a long time ago: Like every other game, Orxonox doesn't show the IO console when building in non-dev release mode. That would mean we either have to implement a message box for errors or just display the console.
Since we don't actually have anything in the 1.0 stable edition, it might really be a good idea.

How exactly should we handle messages like "You killed Player2"? Should we just display the notification or should we also write that to the log as important user info?
And how do we define whether a message is worthy of being sent to the notification system? I get the feeling that this can actually be quite well defined, but I currently don't see how ^^

There is one more point I mentioned and it was actually about changing the logging system. But it would take 10 minutes to do it, so I suggest to consider it:
Used different macros for different purposes, like DOUT, UOUT or whatever seems appropriate. If we cannot find any macros that don't seem to have common names (to avoid collisions), then never mind my suggestion.
Otherwise, this could save typing while keeping all the information. It might also make automatic identification easier.
http://www.xkcd.com/
A webcomic of romance, sarcasm, math, and language.

User avatar
x3n
Baron Vladimir Harkonnen
Posts: 810
Joined: Mon Oct 30, 2006 5:40 pm
Contact:

Re: Output levels

Post by x3n » Sun Jun 19, 2011 4:23 pm

1337 wrote:That makes me recall that I wanted to reconsider a decision I made a long time ago: Like every other game, Orxonox doesn't show the IO console when building in non-dev release mode. That would mean we either have to implement a message box for errors or just display the console.
Since we don't actually have anything in the 1.0 stable edition, it might really be a good idea.
Good point... maybe we should always display the console as long as orxonox is still in beta state. Later we can display errors in a message box if necessary. Or maybe there are other ways, for example we could use the loading screen to show errors during loading a level.
1337 wrote:How exactly should we handle messages like "You killed Player2"? Should we just display the notification or should we also write that to the log as important user info?
And how do we define whether a message is worthy of being sent to the notification system? I get the feeling that this can actually be quite well defined, but I currently don't see how ^^
As I mentioned in my first post, "Chat and kill-messages should not be treated as output, more like notifications". These are messages created by the game logic, not by the framework. Damian built a notification system, Sandro a chat window, so we have already a separation of notifications and chat from the rest of the output. In fact the chat you see in the console is only a copy of the real chat message. So it's really easy to remove that and display it only in overlays on the screen.
1337 wrote:Used different macros for different purposes, like DOUT, UOUT or whatever seems appropriate. If we cannot find any macros that don't seem to have common names (to avoid collisions), then never mind my suggestion.
Otherwise, this could save typing while keeping all the information. It might also make automatic identification easier.
Yeah that's a difficult point. I'm not sure what's the most convenient and at the same time "correct" solution... Here are some possibilities:
  • COUT(0): a number to define the output level, this is what we have now
  • COUT(USER_ERROR): a named constant to define the output level
  • COUT(USER | ERROR): a OR combination of "target" and "type" to define the output level
  • USER_COUT(ERROR): the "target" is part of the macro, the "type" is a named constant
  • COUT_USER(ERROR): same as above but easier auto-completion in the IDE
  • UCOUT(ERROR) or COUTU(ERROR): same as above but shorter
  • ERROR_COUT(USER): the "type" is part of the macro, the "target" is a named constant
  • etc...
  • COUT_USER_ERROR: everything in a macro, even easier for auto-completion
Well you see there are lots of possibilities and you can find a reason for each of them. I think an important question is: should we separate the "target" (user, internal, ...) and the "type" (error, status, ...) of the output level or should they "stick" together? Also how much do we really gain with shorter macros? I mean I definitely see the need for a fast DOUT macro... but for the other levels?

My suggestion in an earlier post was COUT(USER_ERROR), but I'm open for your opinions.
Fabian 'x3n' Landau, Orxonox developer

User avatar
1337
Baron Vladimir Harkonnen
Posts: 521
Joined: Wed Oct 10, 2007 7:59 am

Re: Output levels

Post by 1337 » Sun Jun 19, 2011 4:51 pm

x3n wrote: Good point... maybe we should always display the console as long as orxonox is still in beta state. Later we can display errors in a message box if necessary. Or maybe there are other ways, for example we could use the loading screen to show errors during loading a level.
This has to be done manually anyway, I just realized.
Maybe I'll update the 0.0.5 Windows binary.
In any case, I'll keep showing it for future release builds.
x3n wrote: Yeah that's a difficult point. I'm not sure what's the most convenient and at the same time "correct" solution... Here are some possibilities:
  • COUT(0): a number to define the output level, this is what we have now
  • COUT(USER_ERROR): a named constant to define the output level
  • COUT(USER | ERROR): a OR combination of "target" and "type" to define the output level
  • USER_COUT(ERROR): the "target" is part of the macro, the "type" is a named constant
  • COUT_USER(ERROR): same as above but easier auto-completion in the IDE
  • UCOUT(ERROR) or COUTU(ERROR): same as above but shorter
  • ERROR_COUT(USER): the "type" is part of the macro, the "target" is a named constant
  • etc...
  • COUT_USER_ERROR: everything in a macro, even easier for auto-completion
Hmm, interesting compilation. Since I'm a huge fan of macro collisions, I would like to rule out these macro names: USER, ERROR, WARNING, DEV and anything that seems too common. This should probably even apply for non macro constants. I just don't want to have wild goose chases every time we do something new in the platform sector (like support OS X, updating OIS or anything alike).
x3n wrote: Well you see there are lots of possibilities and you can find a reason for each of them. I think an important question is: should we separate the "target" (user, internal, ...) and the "type" (error, status, ...) of the output level or should they "stick" together? Also how much do we really gain with shorter macros? I mean I definitely see the need for a fast DOUT macro... but for the other levels?

My suggestion in an earlier post was COUT(USER_ERROR), but I'm open for your opinions.
To make the transition as smooth as possible, my suggestion is to keep the levels in the parentheses and instead replace COUT by new names. Since we're in the 21st century of full HD displays and sophisticated IDEs, I agree that writing it out is probably the best option. I liked that in the other Logging system I mentioned before. It was slightly different though.
Hmm, I see that my propositions would imply that we keep the levels as numbers. And that's actually something that's been bugging me ever since.
Since macro constants are mostly in capital letters (assert, max, min etc. being the exceptions), we could do this:

Code: Select all

COUT_USER(error)
Or another solution to the macro problem:

Code: Select all

COUT_USER(ORXERR)
Or:

Code: Select all

COUT_USER(ORX_ERR)
Or:

Code: Select all

COUT_USER(ORX_ERROR)
Or in emphasis of what it actually does (but in contrast to minimal changes):

Code: Select all

LOG_USER(...)
A lot of suggestions from the both of us and little resolve ^^
http://www.xkcd.com/
A webcomic of romance, sarcasm, math, and language.

User avatar
x3n
Baron Vladimir Harkonnen
Posts: 810
Joined: Mon Oct 30, 2006 5:40 pm
Contact:

Re: Output levels

Post by x3n » Sun Jun 19, 2011 6:25 pm

Hey I actually like your last suggestion. We could define the output macros completely different: COUT prints to the console and LOG to the logfile. The only disadvantages of this solution is that A) LOG is likely to cause macro collisions and B) it makes it less obvious that both are basically the same except for the level (and that you can still re-configure the desired output levels to print both to the console (or none)). However using non-number levels hides this fact anyway.

Appart from that, now that we have more or less well-defined guidelines for output and a limited amount of output in both console and logfile, there's also less need for a macro. Remember, the only reason why COUT is a macro is that we can remove output from the release compilation using orxonox::hardDebugLevel. Now this is only required for the verbose log output and this can remain a macro. So without macros we have some more freedom to avoid name collisions.
Fabian 'x3n' Landau, Orxonox developer

User avatar
1337
Baron Vladimir Harkonnen
Posts: 521
Joined: Wed Oct 10, 2007 7:59 am

Re: Output levels

Post by 1337 » Sun Jun 19, 2011 6:56 pm

Just a note: macros are also required for the soft debug level. But that falls into the same category. But the argumentation stays the same.
And I like not using macros ;)

There is just one thing that bugs me a little bit: When making changes to a specific part of the game, one might want to see higher output in the console, maybe even stuff that only goes to the log file.
http://www.xkcd.com/
A webcomic of romance, sarcasm, math, and language.

User avatar
x3n
Baron Vladimir Harkonnen
Posts: 810
Joined: Mon Oct 30, 2006 5:40 pm
Contact:

Re: Output levels

Post by x3n » Sun Jun 19, 2011 9:00 pm

Well yeah, that's exactly what I try to achieve with the contexts, at least for verbose output. But we could use contexts also for normal log output. In fact the code snippes in one of my posts shows already that this is possible. Of course contexts are always optional.

However I'm not sure if this suits your needs. For example, if you have some verbose output of context "network" and some log output of context "network" and you activate this context for the console, then you will see both verbose and log output in the console. There's no easy way to enable the context only for the log output as far as I planned this system. I'm not sure if this is an issue though.
Fabian 'x3n' Landau, Orxonox developer

Post Reply

Who is online

Users browsing this forum: No registered users and 15 guests