Opened 17 years ago
Last modified 5 years ago
#7820 new defect
[PATCH] Syslog Logging Not Working on FreeBSD
| Reported by: | Owned by: | ||
|---|---|---|---|
| Priority: | normal | Milestone: | next-dev-1.7.x |
| Component: | general | Version: | none |
| Severity: | normal | Keywords: | patch syslog freebsd bitesized logging |
| Cc: | packet@… | Branch: | |
| Release Notes: |
The logger can be configured using a Configuration File. |
||
| API Changes: | |||
| Internal Changes: | |||
Description
FreeBSD's syslog doesn't listen on /dev/log. It uses /var/run/log. Attached is a patch that allows you to specify the path to the UNIX socket instead of hardcoding it. It basically uses the logfile parameter, if it's None use /dev/log otherwise use it.
This bug affects all versions of Trac since about 0.7 it looks like.
Attachments (5)
Change History (29)
by , 17 years ago
| Attachment: | syslog-path.patch added |
|---|
by , 17 years ago
| Attachment: | syslog-removepath.patch added |
|---|
It's also possible to just remove the explicit path, and everything Just Works(tm) (at least on Python 2.5.2).
comment:1 by , 17 years ago
| Milestone: | → 0.13 |
|---|
My preference goes to attachment:syslog-removepath.patch.
Moving to 0.13 so that we don't have to bother with Python 2.3.
Should be verified for 2.4 as well, and on other platforms if needed (MacOS X?)
comment:3 by , 15 years ago
| Cc: | added |
|---|
According to the Python documentation:
- Passing no argument to
SysLogHandlerconnects to the syslog via UDP port 514 onlocalhost. - Specifying a string argument to
SysLogHandleris only documented since 2.5, but is actually supported earlier (2.3 is the oldest I checked), and connects to a UNIX socket.
Considering this, we could support both variants, which comes closer to the first patch:
- Add a new parameter
logdest. - If
logdeststarts withUDP:, we pass the remaining string as a hostname and log via UDP to that host (which could be localhost). This would also allow logging remotely. - Otherwise,
logdestis passed as a string and we log to a UNIX socket.
Re-using logfile for this purpose is probably a bad idea, as the default value is trac.log.
comment:5 by , 10 years ago
#11216 closed as a duplicate, additionally requesting the ability to set the syslog facility. ticket:11216:logging_config.patch adds a log_config option which points to a dedicated logging configuration file.
by , 10 years ago
| Attachment: | logging_config.patch added |
|---|
Updated logging config patch. Adds the path, basename, project log format substitutions.
by , 10 years ago
| Attachment: | logging.ini added |
|---|
Logging config ini file to log to syslog on FreeBSD
comment:6 by , 10 years ago
| Cc: | added |
|---|
by , 10 years ago
| Attachment: | logging_config_adminpanel.patch added |
|---|
Patch to the admin panel to add log_config support.
comment:7 by , 10 years ago
The patch looks pretty good. The biggest thing that will delay getting this committed is the lack of unit tests. If some unit tests were added this could be included in milestone:1.2.
comment:8 by , 10 years ago
See also #11874. The proposed changes in that ticket would be a good follow-on to this ticket.
comment:9 by , 10 years ago
| Keywords: | logging added |
|---|---|
| Milestone: | next-major-releases → 1.2 |
comment:10 by , 10 years ago
| Owner: | set to |
|---|---|
| Status: | new → assigned |
comment:11 by , 10 years ago
Minor refactorings in [14333:14336].
Revised changes in log:rjollos.git:t7820_logging_config. The revised changes avoid API changes that were present in attachment:logging_config.patch. Some of those changes have been deferred to #11874 (comment:10:ticket:11874).
I'll do more testing and add unit tests.
comment:13 by , 10 years ago
At least, we should use disable_existing_loggers=False for the logging.config.fileConfig(). I guess that call of the fileConfig() would stop loggers of other environments with multiple projects.
See:
comment:14 by , 10 years ago
| Release Notes: | modified (diff) |
|---|
comment:15 by , 10 years ago
| Keywords: | patch added |
|---|
comment:16 by , 10 years ago
| Milestone: | 1.2 → 1.3.1 |
|---|
follow-up: 19 comment:18 by , 9 years ago
The resource of the logging handler isn't closed even though calling Environment.shutdown().
logging.ini has the following.
[formatters]
keys=form01
[logger_root]
level=NOTSET
handlers=hand01
[handler_hand01]
class=FileHandler
level=NOTSET
formatter=form01
args=('/tmp/trac.log',)
[formatter_form01]
class=logging.Formatter
format=Trac %(asctime)s %(levelname)s %(message)s
After constructing Environment object, the logger is initialized and the /tmp/trac.log is opened.
>>> from trac.env import Environment >>> env = Environment('/home/jun66j5/var/trac/1.3dev-sqlite') >>> import os >>> os.getpid() 4625 >>> os.system('lsof -p 4625 | tail -4') python 4625 jun66j5 0u CHR 136,0 0t0 3 /dev/pts/0 python 4625 jun66j5 1u CHR 136,0 0t0 3 /dev/pts/0 python 4625 jun66j5 2u CHR 136,0 0t0 3 /dev/pts/0 python 4625 jun66j5 3w REG 8,1 14517 268820 /tmp/trac.log 0
However, the /tmp/trac.log is still opened after call of Environment.shutdown(). No way to close the resource.
>>> env.shutdown() >>> os.system('lsof -p 4625 | tail -4') python 4625 jun66j5 0u CHR 136,0 0t0 3 /dev/pts/0 python 4625 jun66j5 1u CHR 136,0 0t0 3 /dev/pts/0 python 4625 jun66j5 2u CHR 136,0 0t0 3 /dev/pts/0 python 4625 jun66j5 3w REG 8,1 14517 268820 /tmp/trac.log 0 >>> del env >>> env Traceback (most recent call last): File "<stdin>", line 1, in <module> NameError: name 'env' is not defined >>> import gc >>> gc.collect() 732 >>> gc.collect() 0 >>> os.system('lsof -p 4625 | tail -4') python 4625 jun66j5 0u CHR 136,0 0t0 3 /dev/pts/0 python 4625 jun66j5 1u CHR 136,0 0t0 3 /dev/pts/0 python 4625 jun66j5 2u CHR 136,0 0t0 3 /dev/pts/0 python 4625 jun66j5 3w REG 8,1 14517 268820 /tmp/trac.log 0
comment:19 by , 9 years ago
Replying to Jun Omae:
The resource of the logging handler isn't closed even though calling
Environment.shutdown().
Thanks for noticing. I have a possible solution for that issue, but there are a few related issues to work through. Handling multiple environments, each with their own logger, may be tricky. I'll post some more changes and comments soon.
comment:20 by , 9 years ago
There are numerous issues that need to be worked out, the first of which is for the Environment to get the name of the logger to use, as pointed out in comment:18. I considered a few ways to approach this:
- Add a
[logging]configuration option,logger_name. This seems like a redundant specification since the logger name is specified in thelogging.inifile, but it could be useful in the case thatlogging.inidefined loggers for several environments, and each environment pointed to the samelogging.ini(which itself presents issues, to be discussed). - Parse
logging.inito get the logger name before callingfileConfig. An imposed constraint would be thatlogging.inican only contain the configuration for single logger, and possibly therootlogger as well. Python 3.4 allows an instance derived fromRawConfigParserto be passed as fname, which would fit this pattern. - Reimplement
fileConfigintrac.log, returning the name of the logger. The constraint of one logger per configuration file (not includingroot), would need to be imposed.
I'm inclined to go with the last solution because the implementation of fileConfig has several issues that could be solved with a rewrite.
fileConfigcalls _install_loggers, which removes all handlers for therootlogger. With multiple environments we might want to use therootlogger to share configuration across all the environments, but we don't want therootlogger to be reset each time an environment reads itslogging.ini.- The internal list of handlers is cleared each time a logging config file is read.
fileConfigdoesn't support incremental configuration.DictConfigdoes support incremental configuration, but I'm not sure the implementation is quite what we want.
The way fileConfig is implemented, I'm inclined to think that the expected use would be to load logging.ini at application scope, then have a logger_name configuration option so that each Environment knows which logger to use. However, Trac doesn't have an application scope configuration whereby we could load the logging configuration at application startup. Or, maybe I'm wrong about this, and Trac's means of application-scope configuration is to use environment variables, which might work in this case.
Side note: the Python documentation recommends using dictConfig rather than fileConfig, but I think fileConfig is pretty close to what we want with Trac since we already use the ini file format for trac.ini. I've studied the source code for logging.config and there are other warts, which I won't go into because I think I see a path to a reasonable solution.
I don't want to overcomplicate the implementation prior to getting feedback on use cases, so I'm suggesting the following constraints:
- Each environment should have its own
logging.inifile and that file should define the name of a single logger that is used only by that environment. - To share a configuration among multiple environments (e.g. have them all log to the same file), the
rootlogger should be configured.
The re-implementation of fileConfig will return the name of the logger that has been read from logging.ini and the Trac environment will clean up the handlers for its loggers on shutdown.
I'm not quite sure how to handle configuring the root logger in a multi-environment configuration. If the root logger is configured in logging.ini for every environment, then it will be recreated when each Environment is created. It's also not clear to me which Environment should be responsible for cleaning up the handlers for the root logger. Maybe that would be accomplished by a shutdown function called by atexit.
On the other hand, if we make a single environment responsible for configuration and cleaning up the root logger, then we need to make sure that environment is started first.
I'm considering something like the following as a solution. Store the logger config in its own file, or use a prefix like file:// (inspired by cfg://), to point to the root config file from every logging.ini. With the logging config in its own file, we could store the timestamp of that file and only reload the root configuration file when the timestamp has changed. I'm assuming we could use a class or module scope variable to store the timestamp so that the timestamp would be seen by all environments running in the same process. However, it's possible I don't understand all the possible runtime configurations that need to be accounted for. I'm assuming that under any configuration, we only need to account for multiple environments running in the same process, and that the state of class or module scope variables will be shared across all environments running in the same process, but no environments running outside the process. I'm also assuming we may need to put a lock on any such variables since they could be written to from multiple threads running in the process.
Another possible solution, mentioned earlier, would be to configure the root logger at application scope.
comment:23 by , 6 years ago
| Owner: | removed |
|---|---|
| Status: | assigned → new |



Patch for 0.10-stable and trunk. Overrides handling of UNIX socket path via logfile parameter.