Hi,--- Synchronet 3.20a-Linux NewsLink 1.114
I have the following in my program:
try:
logging.config.fileConfig(args.config_file)
config = configparser.ConfigParser()
config.read(args.config_file)
if args.verbose:
print(f"Configuration file: {args.config_file}")
except FileNotFoundError:
print(f"Error: configuration file {args.config_file} not found. Exiting.")
sys.exit(0)
and when I ran the program I got the error
Error: configuration file /usr/local/etc/sc_mailer not found. Exiting.
However, this file *does* exist and *can* be read. By checking the 'filename' attribute of the exception I discovered that the problem was
the log file defined *in* the config file, namely
[handler_fileHandler]
class=FileHandler
level=DEBUG
formatter=defaultFormatter
args=('/var/log/my_prog.log', 'a')
This log file did not exist. The exception is thrown by
logging.config.fileConfig(args.config_file)
My questions are:
1. Should I be surprised by this behaviour?
2. In terms of generating a helpful error message, how should one
distinguish between the config file not existing and the log file not
existing?
Cheers,
Loris
--
This signature is currently under constuction.
--
https://mail.python.org/mailman/listinfo/python-list
I have the following in my program:
try:
logging.config.fileConfig(args.config_file)
config = configparser.ConfigParser()
config.read(args.config_file)
if args.verbose:
print(f"Configuration file: {args.config_file}")
except FileNotFoundError:
print(f"Error: configuration file {args.config_file} not found. Exiting.")
...
My questions are:
1. Should I be surprised by this behaviour?
2. In terms of generating a helpful error message, how should one
distinguish between the config file not existing and the log file not
existing?
except FileNotFoundError:
print(f"Error: configuration file {args.config_file} not found.
Exiting.")
sys.exit(0)
and when I ran the program I got the error
Error: configuration file /usr/local/etc/sc_mailer not found.
Exiting.
However, this file *does* exist and *can* be read.
I have the following in my program:
try:
logging.config.fileConfig(args.config_file)
config = configparser.ConfigParser()
config.read(args.config_file)
if args.verbose:
print(f"Configuration file: {args.config_file}")
except FileNotFoundError:
print(f"Error: configuration file {args.config_file} not found. Exiting.")
Do not replace full error information (including a traceback)
with your own reduced error message.
If you omit your "try ... except FileNotFoundError`
(or start the `except` clause with a `raise`), you
will learn where in the code the exception has been raised
and likely as well what was not found (Python is quite good
with such error details).
2. In terms of generating a helpful error message, how should one
distinguish between the config file not existing and the log file not
existing?
On 11Nov2024 18:24, dieter.maurer@online.de <dieter.maurer@online.de>
wrote:
Loris Bennett wrote at 2024-11-11 15:05 +0100:My questions are:
I have the following in my program:
try:
logging.config.fileConfig(args.config_file)
config = configparser.ConfigParser()
config.read(args.config_file)
if args.verbose:
print(f"Configuration file: {args.config_file}")
except FileNotFoundError:
print(f"Error: configuration file {args.config_file} not
found. Exiting.")
1. Should I be surprised by this behaviour?
2. In terms of generating a helpful error message, how should one
distinguish between the config file not existing and the log file not >>> existing?
Generally you should put a try/except around the smallest possible piece
of code. So:
config = configparser.ConfigParser()
try:
config.read(args.config_file)
except FileNotFoundError as e:
print(f"Error: configuration file {args.config_file} not found:
{e}")
This way you know that the config file was missing.
2. In terms of generating a helpful error message, how should one
distinguish between the config file not existing and the log file not
existing?
On 11Nov2024 18:24, dieter.maurer@online.de <dieter.maurer@online.de> wrote:
Loris Bennett wrote at 2024-11-11 15:05 +0100:
I have the following in my program:
try:
logging.config.fileConfig(args.config_file)
config = configparser.ConfigParser()
config.read(args.config_file)
if args.verbose:
print(f"Configuration file: {args.config_file}")
except FileNotFoundError:
print(f"Error: configuration file {args.config_file} not found. Exiting.")
Do not replace full error information (including a traceback)
with your own reduced error message.
If you omit your "try ... except FileNotFoundError`
(or start the `except` clause with a `raise`), you
will learn where in the code the exception has been raised
and likely as well what was not found (Python is quite good
with such error details).
Actually, file-not-found is pretty well defined - the except action
itself is fine in that regard.
[...]
2. In terms of generating a helpful error message, how should one
distinguish between the config file not existing and the log file not
existing?
Generally you should put a try/except around the smallest possible
piece of code. So:
config = configparser.ConfigParser()
try:
config.read(args.config_file)
except FileNotFoundError as e:
print(f"Error: configuration file {args.config_file} not found: {e}")
This way you know that the config file was missing.
On Tue, 12 Nov 2024 at 01:59, Loris Bennett via Python-list <python-list@python.org> wrote:
2. In terms of generating a helpful error message, how should one
distinguish between the config file not existing and the log file not
existing?
By looking at the exception's attributes rather than assuming and
hard-coding the path in your message? Or, even better, just let the
exception bubble.
On Tue, 12 Nov 2024 at 01:59, Loris Bennett via Python-list <python-list@python.org> wrote:
2. In terms of generating a helpful error message, how should one
distinguish between the config file not existing and the log file not
existing?
By looking at the exception's attributes rather than assuming and
hard-coding the path in your message? Or, even better, just let the
exception bubble.
Poor error reporting is a very common problem in programming. Python
is not anything special in this case. Of course, it would've been
better if the error reported what file wasn't found. But, usually
these problems are stacking, like in your code. Unfortunately, it's
your duty, as the language user, to anticipate those problems and act accordingly. Now you've learned that the one file you believe that
could be the source for the error isn't the only one--well, adjust
your code to differentiate between those two (and potentially other?)
cases. There's very little else you can do beside that.
NB. On the system level, the error has no information about what file
wasn't found. It simply returns some numeric value (the famous
ENOENT) in case when the system call to open a file fails. Python
could've been more helpful by figuring out what path caused the
problem and printing that in the error message, but it doesn't...
That's why I, myself, never use the vanilla FileNotFoundError, I
always re-rise it with a customized version that incorporates the
information about the missing file in the error message.
NB2. It's always a bad idea to print logs to files. Any sysadmin /
ops / infra person worth their salt will tell you that. The only
place the logs should go to is the standard error. There are true and
tried tools that can pick up logs from that point on, and do with them whatever your heart desires. That is, of course, unless you are
creating system tools for universal log management (in which case, I'd question the choice of Python as a suitable language for such a task). Unfortunately, even though this has been common knowledge for decades,
it's still elusive in the world of application development :|
On Mon, Nov 11, 2024 at 4:00 PM Loris Bennett via Python-list <python-list@python.org> wrote:--
Hi,
I have the following in my program:
try:
logging.config.fileConfig(args.config_file)
config = configparser.ConfigParser()
config.read(args.config_file)
if args.verbose:
print(f"Configuration file: {args.config_file}")
except FileNotFoundError:
print(f"Error: configuration file {args.config_file} not found. Exiting.")
sys.exit(0)
and when I ran the program I got the error
Error: configuration file /usr/local/etc/sc_mailer not found. Exiting.
However, this file *does* exist and *can* be read. By checking the
'filename' attribute of the exception I discovered that the problem was
the log file defined *in* the config file, namely
[handler_fileHandler]
class=FileHandler
level=DEBUG
formatter=defaultFormatter
args=('/var/log/my_prog.log', 'a')
This log file did not exist. The exception is thrown by
logging.config.fileConfig(args.config_file)
My questions are:
1. Should I be surprised by this behaviour?
2. In terms of generating a helpful error message, how should one
distinguish between the config file not existing and the log file not
existing?
Cheers,
Loris
--
This signature is currently under constuction.
--
https://mail.python.org/mailman/listinfo/python-list
On 11Nov2024 18:24, dieter.maurer@online.de <dieter.maurer@online.de> wrote: >>Loris Bennett wrote at 2024-11-11 15:05 +0100:The original exception likely tells us which file was not found.
I have the following in my program:
try:
logging.config.fileConfig(args.config_file)
config = configparser.ConfigParser()
config.read(args.config_file)
if args.verbose:
print(f"Configuration file: {args.config_file}")
except FileNotFoundError:
print(f"Error: configuration file {args.config_file} not found. Exiting.")
Do not replace full error information (including a traceback)
with your own reduced error message.
If you omit your "try ... except FileNotFoundError`
(or start the `except` clause with a `raise`), you
will learn where in the code the exception has been raised
and likely as well what was not found (Python is quite good
with such error details).
Actually, file-not-found is pretty well defined - the except action
itself is fine in that regard.
Regarding your example above, if 'missingfile.py' contains the followingWell:
import configparser
config = configparser.ConfigParser()
try:
config.read('/foo/bar')
except FileNotFoundError as e:
print(f"Error: configuration file {config_file} not found: {e}")
them
python3 missingfile.py
does not produce an any output for me and so does not seem to be a
reliable way of handling the case where the config file does not exist.
Help on method read in module configparser:help(config.read)
I am not entirely convinced by NB2. I am, in fact, a sort of sysadmin
person and most of my programs write to a log file. The programs are
also moderately complex, so a single program might access a database,
query an LDAP server, send email etc., so potentially quite a lot can go wrong. They are also not programs whose output I would pipe to another command. What would be the advantage of logging to stderr? Quite apart
from that, I find having a log file a useful for debugging when I am developing.
Finally, if you want your logs to go to a file, and currently, your
only option is stderr, your shell gives you a really, really simple
way of redirecting stderr to a file. So, really, there aren't any
excuses to do that.
On 11/12/24 12:10, Left Right via Python-list wrote:
Finally, if you want your logs to go to a file, and currently, your
only option is stderr, your shell gives you a really, really simple
way of redirecting stderr to a file. So, really, there aren't any
excuses to do that.
an awful lot of the programs that need to do extensive logging don't run under control of a shell, and thus "shell redirection" helps not at all.
Cameron Simpson<cs@cskk.id.au> writes:That is excellent advice.
Generally you should put a try/except around the smallest possible
piece of code.
--- Synchronet 3.20a-Linux NewsLink 1.114So:
config = configparser.ConfigParser()
try:
config.read(args.config_file)
except FileNotFoundError as e:
print(f"Error: configuration file {args.config_file} not found: {e}")
since logs are designed to grow indefinitely, the natural
response to this design property is log rotation.
But, it's
impossible to reliably rotate a log file. There's always a chance
that during the rotation some log entries will be written to the file
past the point of rotation, but prior to the point where the next logs
volume starts.
You seem to be thinking of a particular way
of rotating log files, where an external process tries to swap the
program's log file out from under it without its knowledge. That could
be vulnerable to race conditions.
I am not entirely convinced by NB2. I am, in fact, a sort of sysadmin
person and most of my programs write to a log file. The programs are
also moderately complex, so a single program might access a database,
query an LDAP server, send email etc., so potentially quite a lot can go
wrong. They are also not programs whose output I would pipe to another
command. What would be the advantage of logging to stderr? Quite apart
from that, I find having a log file a useful for debugging when I am
developing.
First, the problem with writing to files is that there is no way to
make these logs reliable. This is what I mean by saying these are unreliable: since logs are designed to grow indefinitely, the natural response to this design property is log rotation. But, it's
impossible to reliably rotate a log file. There's always a chance
that during the rotation some log entries will be written to the file
past the point of rotation, but prior to the point where the next logs
volume starts.
There are similar reliability problems with writing to Unix or
Internet sockets, databases etc. For different reasons, but at the
end of the day, whoever wants logs, they want them to be reliable.
Both simplicity and convention selected for stderr as the only and the
best source of logging output.
Programs that write their output to log files will always irritate
their users because users will have to do some detective work to
figure out where those files are, and in some cases they will have to
do administrative works to make sure that the location where the
program wants to store the log files is accessible, has enough free
space, is speedy enough etc.
So, from the ops perspective, whenever I
come across a program that tries to write logs to anything other than
stderr, I make an earnest effort to throw that program into the gutter
and never touch it again. It's too much headache to babysit every
such program, to remember the location of the log files of every such program, the required permissions, to provision storage. If you are
in that line of work, you just want all logs to go to the same place (journal), where you can later filter / aggregate / correlate and
perform other BI tasks as your heart desires.
Of course, if you only administer your own computer, and you have low
single digits programs to run, and their behavior doesn't change
frequently, and you don't care to drop some records every now and
then... it's OK to log to files directly from a program. But then you
aren't really in the sysadmin / infra / ops category, as you are more
of a hobby enthusiast.
Finally, if you want your logs to go to a file, and currently, your
only option is stderr, your shell gives you a really, really simple
way of redirecting stderr to a file. So, really, there aren't any
excuses to do that.
I am not entirely convinced by NB2. I am, in fact, a sort of sysadmin person and most of my programs write to a log file. The programs are
also moderately complex, so a single program might access a database,
query an LDAP server, send email etc., so potentially quite a lot can go wrong. They are also not programs whose output I would pipe to another command. What would be the advantage of logging to stderr? Quite apart from that, I find having a log file a useful for debugging when I am developing.
First, the problem with writing to files is that there is no way to
make these logs reliable. This is what I mean by saying these are unreliable: since logs are designed to grow indefinitely, the natural response to this design property is log rotation. But, it's
impossible to reliably rotate a log file. There's always a chance
that during the rotation some log entries will be written to the file
past the point of rotation, but prior to the point where the next logs
volume starts.
Of course, if you only administer your own computer, and you have lowI would not use my scheme for something released to a wider audience.
single digits programs to run, and their behavior doesn't change
frequently, and you don't care to drop some records every now and
then... it's OK to log to files directly from a program. But then you
aren't really in the sysadmin / infra / ops category, as you are more
of a hobby enthusiast.
Finally, if you want your logs to go to a file, and currently, yourI feel this is the worst of both worlds. Now your program doesn't have
only option is stderr, your shell gives you a really, really simple
way of redirecting stderr to a file.
...
However, it strikes me as not immediately obvious that the logging file
must exist at this point. I can imagine a situation in which I want to >configure a default log file and create it if it missing.
Loris Bennett wrote at 2024-11-12 10:00 +0100:
...
However, it strikes me as not immediately obvious that the logging file >>must exist at this point. I can imagine a situation in which I want to >>configure a default log file and create it if it missing.
This is what happens usually:
if you open a file with mode `a` or `w`, the file is created
if it does not yet exist.
Thus, a missing log file should not give you the `FileNotFound`
exception.
Look at the exception details: they should tell you what really
was not found (maybe the directory for the logfile).
But, it's
impossible to reliably rotate a log file. There's always a chance
that during the rotation some log entries will be written to the file
past the point of rotation, but prior to the point where the next logs
volume starts.
On any Unix system this is untrue. Rotating a log file is quite simple:
On any Unix system this is untrue. Rotating a log file is quite simple:
I realized I posted this without cc'ing the list: http://jdebp.info/FGA/do-not-use-logrotate.html .
The link above gives a more detailed description of why log rotation
on the Unix system is not only not simple, but is, in fact,
unreliable.
What I most often do is use one logfile per day, with the date in the filename. Then simply delete all files older than 7 days, or 30 days, or whatever is useful for the task at hand. Not only does that sidestep any issues with rotating logs, but I also find it's very useful to have the
date in the filename.
On 14 Nov 2024, at 14:07, Loris Bennett via Python-list <python-list@python.org> wrote:On almost all Linux distros you would run a long running program as a systemd service and let it put logs into the journal. I wonder if that was what was being hinted at?
I don't quite understand what your suggestion is. Do you mean that I
should log to stderr and then run my program as
my_program ... 2>&1 | logger
On any Unix system this is untrue. Rotating a log file is quite simple:
I realized I posted this without cc'ing the list: http://jdebp.info/FGA/do-not-use-logrotate.html .
The link above gives a more detailed description of why log rotation
on the Unix system is not only not simple, but is, in fact,
unreliable.
NB. Also, it really rubs me the wrong way when the word "standard" is
used to mean "common" (instead of "as described in a standard
document").
And when it comes to popular tools, oftentimes "common"
is wrong because commonly the tool is used by amateurs rather than
experts. In other words, you only reinforced what I wrote initially:
plenty of application developers don't know how to do logging well.
It also appears that they would lecture infra / ops people on how to
do something that they aren't experts on, while the latter are :)
On any Unix system this is untrue. Rotating a log file is quite simple:
I realized I posted this without cc'ing the list: http://jdebp.info/FGA/do-not-use-logrotate.html .
The link above gives a more detailed description of why log rotation
on the Unix system is not only not simple, but is, in fact,
unreliable.
On 11/14/24 12:03 AM, Left Right wrote:
On any Unix system this is untrue. Rotating a log file is quite simple:
I realized I posted this without cc'ing the list:
http://jdebp.info/FGA/do-not-use-logrotate.html .
The link above gives a more detailed description of why log rotation
on the Unix system is not only not simple, but is, in fact,
unreliable.
Nothing in that article contradicts what I said about renaming log
files. His argument is that renaming log files messes with tail -F, and therefore broken and unreliable. Which a pretty strange argument. tail
-F might not see some data during the rotation, but the log files
themselves don't miss anything, which was my contention. In all my
years of sysadmin-ing I have never once worried about problems GNU tail
might have with a file that gets rotated out from under you. Not sure
why the author is so fixated on it.
Sysop: | DaiTengu |
---|---|
Location: | Appleton, WI |
Users: | 1,007 |
Nodes: | 10 (0 / 10) |
Uptime: | 203:54:28 |
Calls: | 13,143 |
Files: | 186,574 |
D/L today: |
615 files (142M bytes) |
Messages: | 3,310,259 |