[Geoserver-devel] Understanding the GeoServer new startup code (and fixing logging in the process)

Hi,
I'm stumbling a little on the new GeoServerLoader class differences
between 1.7.x and trunk and guess I need some clarifications.

The context in which I'm operating is some logging changes, and in
the process I've looked into how the whole configuration is loaded.

On 1.7.x, first service.xml is loaded to retrieve logging configuration,
then logging is configured, then the catalog and the services information is loaded, and finally a series of pluggable initializers
is processed (for stuff that you need to do at startup, but after the
normal configuration has been processed).

On trunk, the initializers are still there, but GeoServerLoader.initialize() is actually never called. What happens
instead is that the Spring context is left free to load the classes
in the order it wants, and GeoServerLoader acts as a post processor,
configuring each of them as it is loaded, and running the
GeoServerInitializer after the service configuration is loaded.
By the time the LoggingInitializer is called, both Catalog and
GeoServer have been loaded.

Now, it's better to initialize logging before the catalog is loaded,
because that operation generates a lot of logs over which it would
be good to have some control.
So the temptation to solve the issue on trunk as well is to:
- make LoggingInitializer a GeoServerPreInitializer, that is,
   a kind of initiliazer that does run before everything else
   is setup, that would be called when GeoServerLoader.setApplicationContext(...) is called, and
   that would just have an initialize() method
- have the LoggingInitializer directly read services.xml and
   configure itself without the need to depend on GeoServer
   (using pieces of the legacy logging reader from 1.6.x)

and finally replicate most of it on 1.7.x as well, for consistency.
Suggestions?

Also note that it took me a few hours in the debugger to figure out the
above, due to the new code and the differences between 1.7.x and trunk.
Having a few scraps of documentation would have helped :wink:

Cheers
Andrea

--
Andrea Aime
OpenGeo - http://opengeo.org
Expert service straight from the developers.

Andrea Aime wrote:

Hi,
I'm stumbling a little on the new GeoServerLoader class differences
between 1.7.x and trunk and guess I need some clarifications.

The context in which I'm operating is some logging changes, and in
the process I've looked into how the whole configuration is loaded.

On 1.7.x, first service.xml is loaded to retrieve logging configuration,
then logging is configured, then the catalog and the services information is loaded, and finally a series of pluggable initializers
is processed (for stuff that you need to do at startup, but after the
normal configuration has been processed).

On trunk, the initializers are still there, but GeoServerLoader.initialize() is actually never called. What happens
instead is that the Spring context is left free to load the classes
in the order it wants, and GeoServerLoader acts as a post processor,
configuring each of them as it is loaded, and running the
GeoServerInitializer after the service configuration is loaded.
By the time the LoggingInitializer is called, both Catalog and
GeoServer have been loaded.

Now, it's better to initialize logging before the catalog is loaded,
because that operation generates a lot of logs over which it would
be good to have some control.
So the temptation to solve the issue on trunk as well is to:
- make LoggingInitializer a GeoServerPreInitializer, that is,
   a kind of initiliazer that does run before everything else
   is setup, that would be called when GeoServerLoader.setApplicationContext(...) is called, and
   that would just have an initialize() method

Actually I remember thinking about logging in particular before when I was setting up xstream persistence. And I actually think it makes more sense to explicitly configure logging as the first thing, instead of depending on an extension point. Actually probably best to do it as a serlet context listener, where we do the redirection of geotools logging.

- have the LoggingInitializer directly read services.xml and
   configure itself without the need to depend on GeoServer
   (using pieces of the legacy logging reader from 1.6.x)

Yeah, this is sort of what I was thinking, but more have it done by LoggingStartupContextListener. The only trouble with this approach is what happens when the user changes the configuration from the UI... so perhaps it won't work in the current "apply everything" system.

Once we move toward a finer grained approach we can add a listener to the config which handles the changes made by the user.

and finally replicate most of it on 1.7.x as well, for consistency.
Suggestions?

I disagree in the mind of stability. I stated when hooking up xstream persistence on trunk that is was very alpha, there are still issues to work out. However I was "under the gun" to get persistence working with the new UI so it had to be done quickly... and sadly I had no time for docs.

Also note that it took me a few hours in the debugger to figure out the
above, due to the new code and the differences between 1.7.x and trunk.
Having a few scraps of documentation would have helped :wink:

Cheers
Andrea

--
Justin Deoliveira
OpenGeo - http://opengeo.org
Enterprise support for open source geospatial.

Justin Deoliveira ha scritto:

Andrea Aime wrote:

Hi,
I'm stumbling a little on the new GeoServerLoader class differences
between 1.7.x and trunk and guess I need some clarifications.

The context in which I'm operating is some logging changes, and in
the process I've looked into how the whole configuration is loaded.

On 1.7.x, first service.xml is loaded to retrieve logging configuration,
then logging is configured, then the catalog and the services information is loaded, and finally a series of pluggable initializers
is processed (for stuff that you need to do at startup, but after the
normal configuration has been processed).

On trunk, the initializers are still there, but GeoServerLoader.initialize() is actually never called. What happens
instead is that the Spring context is left free to load the classes
in the order it wants, and GeoServerLoader acts as a post processor,
configuring each of them as it is loaded, and running the
GeoServerInitializer after the service configuration is loaded.
By the time the LoggingInitializer is called, both Catalog and
GeoServer have been loaded.

Now, it's better to initialize logging before the catalog is loaded,
because that operation generates a lot of logs over which it would
be good to have some control.
So the temptation to solve the issue on trunk as well is to:
- make LoggingInitializer a GeoServerPreInitializer, that is,
   a kind of initiliazer that does run before everything else
   is setup, that would be called when GeoServerLoader.setApplicationContext(...) is called, and
   that would just have an initialize() method

Actually I remember thinking about logging in particular before when I was setting up xstream persistence. And I actually think it makes more sense to explicitly configure logging as the first thing, instead of depending on an extension point. Actually probably best to do it as a serlet context listener, where we do the redirection of geotools logging.

- have the LoggingInitializer directly read services.xml and
   configure itself without the need to depend on GeoServer
   (using pieces of the legacy logging reader from 1.6.x)

Yeah, this is sort of what I was thinking, but more have it done by LoggingStartupContextListener. The only trouble with this approach is what happens when the user changes the configuration from the UI... so perhaps it won't work in the current "apply everything" system.

Once we move toward a finer grained approach we can add a listener to the config which handles the changes made by the user.

What we can do is to create the servlet/context listener that reads
the service.xml to perform the initial setup of the logging, and
then add the proper configuration listener using a GeoServer initializer. Since the two classes would share most of the code, we
can create a LoggingUtils where most of the meat is located.

And... ugh... well ok, the listener will have the ServletContext
but not the application context handy, so I guess I'll have to
make two methods named GeoServerExtensions.getProperty, one that
does not take anything and levereages the WebApplicationContext,
and the other that does take a ServletContext (in order to do
the lookup of a property in system props, web.xml and environment).

and finally replicate most of it on 1.7.x as well, for consistency.
Suggestions?

I disagree in the mind of stability.

Hum... hum... ok, so I'll have to cook two completely different
patches for 1.7.x and trunk (for http://jira.codehaus.org/browse/GEOS-1671). Bummer... but yeah, I
can do it.

Cheers
Andrea

--
Andrea Aime
OpenGeo - http://opengeo.org
Expert service straight from the developers.

What we can do is to create the servlet/context listener that reads
the service.xml to perform the initial setup of the logging, and
then add the proper configuration listener using a GeoServer initializer. Since the two classes would share most of the code, we
can create a LoggingUtils where most of the meat is located.

+1.

And... ugh... well ok, the listener will have the ServletContext
but not the application context handy, so I guess I'll have to
make two methods named GeoServerExtensions.getProperty, one that
does not take anything and levereages the WebApplicationContext,
and the other that does take a ServletContext (in order to do
the lookup of a property in system props, web.xml and environment).

Yeah... that class is starting to see some bloat. However... code that lookup a property in a ServletContext would be part of getProperty(ApplicationContext) regardless. So this is just factoring that bit out into getProeprty(ServeltContext) so it can be called by client code?

and finally replicate most of it on 1.7.x as well, for consistency.
Suggestions?

I disagree in the mind of stability.

Hum... hum... ok, so I'll have to cook two completely different
patches for 1.7.x and trunk (for http://jira.codehaus.org/browse/GEOS-1671). Bummer... but yeah, I
can do it.

Yup its a pain... but with the new ui and config persistence there is quite a divergence. Maintaining patches in those sub systems will be duplicated work... not sure how we can get around that one.

Cheers
Andrea

--
Justin Deoliveira
OpenGeo - http://opengeo.org
Enterprise support for open source geospatial.