I am probably over thinking this but I can't seem to make up my mind on which situations call for one or the other. An example would be a program that reads from a file and then does something with that data. If the file does not exist, the program logs a "file not found" message and exits. Would this be considered an "error" error or "fatal" error?
I guess it's just the term but in my mind fatal seems quite egregious, as in "the program just broke, cannot continue and is now exiting without a choice" as apposed to "the program couldn't complete a necessary task for some reason (e.g. file not found) and is choosing to exit because there is no point in continuing".
(and yes I have read the explanation in the docs)
If your program has no choice at all but to exit, use fatal
If your program can recover in some way from the error, use error
For me too it's hard to tell when to use "fatal", "error", and "warning".
I would probably stick to "fatal" only for programmer's errors, i.e., error conditions that are not due to the user or the system where the program is running but to some flaw in the program itself. (This is the case if some assert fails, for example.) This is motivated by the fact that the user can do very little to fix the error and make the program work (apart from reporting the bug and hoping that it gets fixed!).
For user/system errors like missing files or wrong input, I would use "error" when the situation is not recoverable at the moment and requires termination, and "warning" when the program can figure out how to continue. In other words, I would use "error" and "warning" when the user has the chance to fix some stuff and re-run the program successfully.
When you think about this it implies your log messages are important. If they are important, they are not logs -- it is important structured information that you should store in a database and enjoy transaction safety and a query language for producing reports.
Yes, I know, you're in love with removing the inherent structure of your data ("everything should be stored as text with error-prone quoting rules connected via Unix pipelines") -- but it's really a bad idea. It was a bad idea back then, it's still a bad idea now.
When you think about this it implies your log messages are important. If they are important, they are not logs -- it is important structured information that you should store in a database and enjoy transaction safety and a query language for producing reports.
Well, I guess this depends on the type of program.
When I run command-line programs that load some data file, run an analysis and produce some output in a matter of seconds or minutes (as the majority of the programs I usually write), I appreciate to differentiate between assertion failures, errors, warnings, information and debug messages (possibly using different colors) because it allows me to quickly spot problems and it's handy when debugging. Structured logs saved in a database to be retrieved later look too complex to me for this context.
On the other side, @Araq's suggestion is surely the best possible option when your program needs a significant time to run (e.g., a simulation running on a HPC cluster) or must be kept running in the background (like a webserver).