[Zope-Coders] new zLOG

Chris McDonough chrism@zope.com
25 Nov 2002 12:31:02 -0500


--=-o8AjRq7bhSIda1y2FyOf
Content-Type: text/plain
Content-Transfer-Encoding: 7bit

On Mon, 2002-11-25 at 12:20, Guido van Rossum wrote:
> This doesn't sound right -- if someone calls LOG(), they expect the
> log message to go somewhere, root or not.

I solved this on this installer branch by creating a "startup handler"
that both buffers log messages and sends them to stdout.  When the
process setuids, zLOG is initialized and the buffer is flushed to the
resulting handlers.

> Does anybody actually run Zope as root?  AFAIK, all customer projects
> that I know of run it as designated user "zope".

That's a decision that we can make but in that case we should explicitly
prevent people from starting as root.  Currently there is some halfbaked
effective user support in Zope, which causes much grief for newbies and
oldbies alike (especially as it relates to logfiles and filestorage
files being written as root).

> zdaemon.py calls setuid() before forking off a child process.
> 
> But zdaemon.py has its own log file, and I like to see its message
> written rather than disappearing.  (This is what got me started on
> this in the first place.)

You may want to try the startup handler.  It's in zLOG.LogHandlers.  I
have attached a file named zope.py that comes from the installer branch
which might help demonstrate its usage.

- C


--=-o8AjRq7bhSIda1y2FyOf
Content-Disposition: attachment; filename=zope.py
Content-Transfer-Encoding: quoted-printable
Content-Type: text/x-python; name=zope.py; charset=ISO-8859-15

###########################################################################=
###
#
# Copyright (c) 2001 Zope Corporation and Contributors. All Rights Reserved=
.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.0 (ZPL).  A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE
#
###########################################################################=
###
"""
This is a replacement for z2.py which can make use of a config file to obta=
in
configuration values (instead of environment variables).  It is
meant to be run from a shell or exec'ed by another program.

Do not change this file unless you know what you're doing. ;-)
"""

import os, sys, getopt, traceback

# assume that this file is sys.argv[0], and that it lives in
# SOFTWARE_HOME

SOFTWARE_HOME=3Dos.path.split(os.path.abspath(os.path.normpath(sys.argv[0])=
))[0]
if SOFTWARE_HOME not in sys.path:
    sys.path.insert(0, SOFTWARE_HOME)

def usage():
    print """
zope.py [--config-location=3Dfilename-or-url] [--sloppy] [--help]
        [--directive=3Dvalue ...]

zope.py starts a Zope instance.

If the config-location option is not passed, an attempt is made to obtain
configuration info from a file in the current working directory named
'zope.conf;.  An alternate absolute or relative filename may be provided, o=
r
a URL may be provided.   The URL should return a file in the same format as=
 the
filesystem config file.

Directives passed in the options list override those found in the config fi=
le.
An example of a directive is "--client_home=3D/var/client_home".  A
complete list of directives can be found in any 'zope.conf' config file.
Directives which compose 'sections' cannot be specified via the
command-line.

If the 'sloppy' argument is present, duplicate definitions for a non-
multiple-value-allowed key/value pair in the config file are ignored.
"""

if __name__ =3D=3D '__main__':
    try:
        from Controller.Directives import DirectiveRegistry, MULTI
        from Controller import Parser
    except ImportError:
        print ("Could not import the Zope 'Controller' package.  This "
               "may indicate that the zope.py file has been relocated "
               "from its typical location inside the Zope 'SOFTWARE_HOME'. =
")
        usage()
        sys.exit(1)

    config_location =3D 'zope.conf'
    overrides =3D {}
    sloppy =3D 0
    # add directives to options list
    directives =3D DirectiveRegistry.namesByPriority()
    longopts =3D [ "help", "sloppy", "config=3D"]
    for name in directives:
        longopts.append('%s=3D' % name)

    try:
        opts, args =3D getopt.getopt(sys.argv[1:], "h", longopts)
    except getopt.GetoptError, v:
        print v
        usage()
        sys.exit(127)
    for k, v in opts:
        if k in ('-h', '--help'):
            usage()
            sys.exit(0)
        elif k =3D=3D '--config':
            config_location =3D v
        elif k =3D=3D '--sloppy':
            sloppy =3D 1
        else:
            if k.startswith('--'):
                k =3D k[2:]
                overrides[k] =3D v

    config =3D Parser.load(config_location, multi=3DMULTI, sloppy=3Dsloppy)
    config.update(overrides)
    # reconfigure registry with config derived from file and overrides
    DirectiveRegistry.reconfigure(config)

    # activate the directives
    DirectiveRegistry.activateDirectives()

    # start Zope
    try:
        from Controller import Main
        Main.start_zope()
    except SystemExit:
        raise
    except:
        try:
            import zLOG
            zLOG.LOG("Zope Initialization", zLOG.PANIC, "Startup exception"=
,
                     error=3Dsys.exc_info())
        except:
            pass
        traceback.print_exc()
        # tell zdaemon not to restart us by setting 255 exit code
        sys.exit(255)

   =20
           =20


--=-o8AjRq7bhSIda1y2FyOf--