UNO Logging API

classic Classic list List threaded Threaded
17 messages Options
Reply | Threaded
Open this post in threaded view
|

UNO Logging API

frank.schoenheit
Hi,

looking for a possibility to implement some client-side logging
facilities in our database drivers, I came across css.util.logging [1] -
a UNO API which promises to provide exactly such capabilities.

Unfortunately, there's no implementation for this API. Furthermore,
trying to implement it revealed some shortcomings, which cannot be
solved with the existing API, since it is already marked "published",
and thus cannot be changed anymore.

I'd like to propose a new logging API, which is modeled after the Java
logging API (though not (yet) as powerful).

Since this involves quite a few new types, I will not introduce them
here in this mail, but I uploaded a zipped version of the
autodoc-generated IDL reference for the proposed com.sun.star.logging
module. You can find it at [2].

Feedback to this proposed API is highly welcome.

Thanks & Ciao
Frank

[1]http://api.openoffice.org/docs/common/ref/com/sun/star/util/logging/module-ix.html
[2]http://udk.openoffice.org/servlets/ProjectDocumentList

---------------------------------------------------------------------
To unsubscribe, e-mail: [hidden email]
For additional commands, e-mail: [hidden email]

Reply | Threaded
Open this post in threaded view
|

Re: UNO Logging API

Mathias Bauer
Frank Schönheit wrote:

> looking for a possibility to implement some client-side logging
> facilities in our database drivers, I came across css.util.logging [1] -
> a UNO API which promises to provide exactly such capabilities.
>
> Unfortunately, there's no implementation for this API. Furthermore,
> trying to implement it revealed some shortcomings, which cannot be
> solved with the existing API, since it is already marked "published",
> and thus cannot be changed anymore.
If there is an API that is neither used nor implemented and obviously
also not good enough: shouldn't we just remove it?

Ciao,
Mathias


--
Mathias Bauer (mba) - Project Lead OpenOffice.org Writer
OpenOffice.org Engineering at Sun: http://blogs.sun.com/GullFOSS
Please don't reply to "[hidden email]".
I use it for the OOo lists and only rarely read other mails sent to it.

---------------------------------------------------------------------
To unsubscribe, e-mail: [hidden email]
For additional commands, e-mail: [hidden email]

Reply | Threaded
Open this post in threaded view
|

Re: UNO Logging API

frank.schoenheit
Hi Mathias,

> If there is an API that is neither used nor implemented and obviously
> also not good enough: shouldn't we just remove it?

I'm all for it, but AFAIK, there's not process for this, yet. For
instance, some build tools would need to be adjusted, since currently, a
build in offapi checks the created type registry for compatibility with
a released type registry - this would break.

To make things worse, css.util.logging is part of the UDK, so the
restrictions for removing it are probably even higher than in offapi.

I plan to deprecate the useless APIs, removing all documentation from
it, and only pointing to the successor API.

Ciao
Frank

--
- Frank Schönheit, Software Engineer         [hidden email] -
- Sun Microsystems                      http://www.sun.com/staroffice -
- OpenOffice.org Base                       http://dba.openoffice.org -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

---------------------------------------------------------------------
To unsubscribe, e-mail: [hidden email]
For additional commands, e-mail: [hidden email]

Reply | Threaded
Open this post in threaded view
|

Re: UNO Logging API

stephan.bergmann
In reply to this post by frank.schoenheit
Frank Schönheit wrote:
> I'd like to propose a new logging API, which is modeled after the Java
> logging API (though not (yet) as powerful).
[...]
> Feedback to this proposed API is highly welcome.

Sorry this feedback is rather late.  Anyway, I am completely confused by
what you propose.  How is client code supposed to obtain an appropriate
logger?  Is there a globally managed set of loggers from which clients
can choose?  (For example, I would assume Java's static Logger.getLogger
to map to a UNO service constructor, or a method at an XLogManager
interface, but not a method at the XLogger interface.)  Excessive calls
to XLogger.logp are potentially expensive in every scenario, not merely
remotely (three strings are marshalled that are potentially not needed
when the given logging level is too fine).  How exactly are
LoggingRemote and XLoggingRemote supposed to help here?  Please elaborate.

(Also, Java has Levels as a fixed enum, not an open set of integers.
Why deviate from that?  Do you think there ever will be need for more
levels than the given seven?)

-Stephan

---------------------------------------------------------------------
To unsubscribe, e-mail: [hidden email]
For additional commands, e-mail: [hidden email]

Reply | Threaded
Open this post in threaded view
|

Re: UNO Logging API

frank.schoenheit
Hi Stephan,

> Sorry this feedback is rather late.  Anyway, I am completely confused by
> what you propose.

Some things in your mail make me think you read the old css.util.logging
API, not the new one. Sure you visited
http://udk.openoffice.org/files/documents/23/3959/logging.zip?

> How is client code supposed to obtain an appropriate logger?

css.logging.LoggerPool.get().getNamedLogger( someName );

> Is there a globally managed set of loggers from which clients
> can choose?

Yes - LoggerPool.

> (For example, I would assume Java's static Logger.getLogger
> to map to a UNO service constructor, or a method at an XLogManager
> interface, but not a method at the XLogger interface.)

In the new versions which I propose there is no method at XLogger which
can be used to obtain another logger. The old API indead had an
XLogger.getLogger, but I'd say somebody here copied from Java without
caring to use proper UNO concepts ...

> Excessive calls
> to XLogger.logp are potentially expensive in every scenario, not merely
> remotely (three strings are marshalled that are potentially not
> needed when the given logging level is too fine).

That's why the new API offers an "isLoggable( LogLevel )" - stolen
from^W^Winspired by the Java API.

> How exactly are
> LoggingRemote and XLoggingRemote supposed to help here? Please elaborate.

Those are not part of the new API, but only the old one.

My understanding of those old remote versions is that somebody had in
mind that calling via bridges - i.e. via the Java-UNO bridge - might
result in the call "ending" in another thread then where it "started".
Thus, an implementation of "log(p)" would not be able to obtain the
thread id of the caller, thuse it needs to be passed. Something like this.

While I to some extent think such a XRemoteLogger interface might be
useful in some scenarios (but completely nonsense if e.g. the same
logger is used across process boundaries), I decided to not define it
for now in the new API.

> (Also, Java has Levels as a fixed enum, not an open set of integers.
> Why deviate from that?  Do you think there ever will be need for more
> levels than the given seven?)

Not true - Java also explicitly allows extending the levels with own
values - see
http://java.sun.com/javase/6/docs/api/java/util/logging/Level.html:

"It is possible for third parties to define additional logging levels by
subclassing Level. In such cases subclasses should take care to chose
unique integer level values ..."

I think while it probably is seldom that one will extend the LogLevels,
it does not do any harm to allow for it.

Ciao
Frank

--
- Frank Schönheit, Software Engineer         [hidden email] -
- Sun Microsystems                      http://www.sun.com/staroffice -
- OpenOffice.org Base                       http://dba.openoffice.org -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

---------------------------------------------------------------------
To unsubscribe, e-mail: [hidden email]
For additional commands, e-mail: [hidden email]

Reply | Threaded
Open this post in threaded view
|

Re: UNO Logging API

stephan.bergmann
In reply to this post by frank.schoenheit
Frank Schönheit - Sun Microsystems Germany wrote:
> Hi Stephan,
>
>> Sorry this feedback is rather late.  Anyway, I am completely confused by
>> what you propose.
>
> Some things in your mail make me think you read the old css.util.logging
> API, not the new one. Sure you visited
> http://udk.openoffice.org/files/documents/23/3959/logging.zip?

Ha!  I clicked the wrong link in your original post, yes.  (Which would
not have happened if the links had been inline.  Are footnoted links a
bad idea in emails?  Maybe.)

Will have a look inside your zip, then...

(At least, this shows that we both think the old interfaces are, well,
unusable.)  :)

>> (Also, Java has Levels as a fixed enum, not an open set of integers.
>> Why deviate from that?  Do you think there ever will be need for more
>> levels than the given seven?)
>
> Not true - Java also explicitly allows extending the levels with own
> values - see
> http://java.sun.com/javase/6/docs/api/java/util/logging/Level.html:

Oops, you are right.  Sorry.

-Stephan

---------------------------------------------------------------------
To unsubscribe, e-mail: [hidden email]
For additional commands, e-mail: [hidden email]

Reply | Threaded
Open this post in threaded view
|

Re: UNO Logging API

stephan.bergmann
In reply to this post by frank.schoenheit
Stephan Bergmann wrote:

> Frank Schönheit - Sun Microsystems Germany wrote:
>> Hi Stephan,
>>
>>> Sorry this feedback is rather late.  Anyway, I am completely confused
>>> by what you propose.
>>
>> Some things in your mail make me think you read the old css.util.logging
>> API, not the new one. Sure you visited
>> http://udk.openoffice.org/files/documents/23/3959/logging.zip?
>
> Ha!  I clicked the wrong link in your original post, yes.  (Which would
> not have happened if the links had been inline.  Are footnoted links a
> bad idea in emails?  Maybe.)
>
> Will have a look inside your zip, then...

Sorry for the delay:

- Should not the singleton be called "theLoggerPool" instead of
"LoggerPool"?

- Is the LoggerPool overkill?  (Why not theDefaultLogger as a singleton
and arbitrarily named loggers as services?)

- What are the initial values of the Encoding, Formatter, Level
attributes of the ConsoleHandler, FileHandler services?  (The
ConsoleHandler curiously uses a component context value to override the
Level, instead of a constructor argument, and instead of having this
consistent across attributes and services.)

- LogRecord members SourceClassName, SourceMethodName (and XLogger.logp
parameters SourceClass, SourceMethod, curiously with different names):
If at the level of UNO, class does not make sense.  If at the level of
implementation, neither class nor method make sense in general.

- LogRecord member ThreadID:  UNO's notion of threads is rather
abstract, there is no universal concept of mapping threads to hyper
values.  (URP uses a mapping from threads to strings.)

-Stephan

---------------------------------------------------------------------
To unsubscribe, e-mail: [hidden email]
For additional commands, e-mail: [hidden email]

Reply | Threaded
Open this post in threaded view
|

Re: UNO Logging API

Jörg Barfurth
In reply to this post by frank.schoenheit
Hi,

Sorry for being late to this discussion. I don't read those lists
continuously any more.

Frank Schönheit schrieb:
> Hi,
>
> looking for a possibility to implement some client-side logging
> facilities in our database drivers, I came across css.util.logging [1] -
> a UNO API which promises to provide exactly such capabilities.
>
> Unfortunately, there's no implementation for this API.

This is not entirely true.

The configmgr backend service has logging capabilities built around this
API. In configmgr/workben/logger a logger component can be built that
takes this log output and dumps it into a file (or on stderr).

If there is trouble with configuration parsing at a customer/user site,
this component can be installed (using the UNO package manager) and
voila - you get log output. The component is crude in some respect (it
is configured via environment variables and the log threshold level is
configured numerically), but it wouldn't take all that much to make it
into something usable.

> Furthermore,
> trying to implement it revealed some shortcomings, which cannot be
> solved with the existing API, since it is already marked "published",
> and thus cannot be changed anymore.
>

I'm not sure which shortcomings you mean and I haven't looked at your
new proposal.

One shortcoming I recall from implementing the above (btw, at that time
I tried to get feedback on a more general logging strategy, but did not
get much of value) is how to obtain a logger for a certain component or
module. As I had nothing to generalize by, I took the simplest solution
for the one-module case I had at hand: the configuration defines a
singleton name, which it will use to get a logger. It doesn't care how
that singleton is populated.

The simple test logger I defined (I also have a multi-platform binary
package for interested parties) registers itself as that singleton. Of
course much more sophisticated solutions that merge and filter log
output from multiple components can also be used in that place.

- Jörg

> I'd like to propose a new logging API, which is modeled after the Java
> logging API (though not (yet) as powerful).
>
> Since this involves quite a few new types, I will not introduce them
> here in this mail, but I uploaded a zipped version of the
> autodoc-generated IDL reference for the proposed com.sun.star.logging
> module. You can find it at [2].
>
> Feedback to this proposed API is highly welcome.
>
> Thanks & Ciao
> Frank
>
> [1]http://api.openoffice.org/docs/common/ref/com/sun/star/util/logging/module-ix.html
> [2]http://udk.openoffice.org/servlets/ProjectDocumentList
>



--
Joerg Barfurth           phone: +49 40 23646662 / x66662
Software Engineer        mailto:[hidden email]
Desktop Technology       http://reserv.ireland/twiki/bin/view/Argus/
Thin Client Software     http://www.sun.com/software/sunray/
Sun Microsystems GmbH    http://www.sun.com/software/javadesktopsystem/


---------------------------------------------------------------------
To unsubscribe, e-mail: [hidden email]
For additional commands, e-mail: [hidden email]

Reply | Threaded
Open this post in threaded view
|

Re: UNO Logging API

frank.schoenheit
Hi Joerg,

> Sorry for being late to this discussion. I don't read those lists
> continuously any more.

(Sigh. Not getting feedback for about two weeks, my CWS is short before
QA by now.)

>> Unfortunately, there's no implementation for this API.
>
> This is not entirely true.
>
> The configmgr backend service has logging capabilities built around this
> API. In configmgr/workben/logger a logger component can be built that
> takes this log output and dumps it into a file (or on stderr).

Didn't know that, I just looked for a registered service in a complete
OOo installation. Also, telling my plans for an implementation in some
larger developer meeting made nobody raise his hand, saying "but there
already is one ...". Sigh, again.

>> Furthermore,
>> trying to implement it revealed some shortcomings, which cannot be
>> solved with the existing API, since it is already marked "published",
>> and thus cannot be changed anymore.
>
> I'm not sure which shortcomings you mean and I haven't looked at your
> new proposal.

Configuration is exactly one of the shortcomings. I wanted to allow
people to change the "output channel", both programmatically and in the
configuration - which lead to stealing the LogHandler concept from the
Java API. Also, when I started implementing the actual output of a
single event, I noticed that it might be desirable to have different
output formats - which lead to stealing the LogFormatter concept from
the Java API.
(I can even imagine that users want to be able to filter the output -
which means that I intend to steal the LogFilter concept from the Java
API, too.)
(And yet more, the ErrorHandler in Java sounds like a reasonable
(advanced) concept. Assuming that loggers are used in low-level
components, there's not much other possibilities to report errors in
e.g. opening the log file.)

Also, as outlined in previous discussions with Stephan here, the
existing API has some strange concepts (XLogger::getLogger, e.g.), which
do not make use (and in some respects contradict) modern UNO API concepts.

> One shortcoming I recall from implementing the above (btw, at that time
> I tried to get feedback on a more general logging strategy, but did not
> get much of value)

Seems I missed it at that time, or didn't feel like bothering with it.

> is how to obtain a logger for a certain component or
> module. As I had nothing to generalize by, I took the simplest solution
> for the one-module case I had at hand: the configuration defines a
> singleton name, which it will use to get a logger. It doesn't care how
> that singleton is populated.

Which is one more shortcoming. The old API has some (crude) way to
retrieve named loggers, the new API makes this a central concept. So a
given component can simply obtain a logger with a name which is specific
to this component.


Ciao
Frank

--
- Frank Schönheit, Software Engineer         [hidden email] -
- Sun Microsystems                      http://www.sun.com/staroffice -
- OpenOffice.org Base                       http://dba.openoffice.org -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

---------------------------------------------------------------------
To unsubscribe, e-mail: [hidden email]
For additional commands, e-mail: [hidden email]

Reply | Threaded
Open this post in threaded view
|

Re: UNO Logging API

frank.schoenheit
In reply to this post by stephan.bergmann
Hi Stephan,

> - Should not the singleton be called "theLoggerPool" instead of
> "LoggerPool"?

A singleton I introduced to this list some time ago (IIRC, it was the
OfficeResourceManager) used the same naming scheme. At this time, you
asked the same question, but we agreed that it's not strictly necessary
to use the "theFoo" scheme at this time. (Or, more precise, the question
whether we should get rid of the "theFoo" convention was not answered.)
This time, I hope to yak you down^W^W^Wconvince you again.

> - Is the LoggerPool overkill?

no, IMO.

> (Why not theDefaultLogger as a singleton
> and arbitrarily named loggers as services?)

Since named loggers as services would give you less freedom (read: more
work) in "introducing" a new logger. With the current way, you can
simply ask the pool for a logger with a given name. Otherwise, you would
need to explicitly define/implement your new logger service.

> - What are the initial values of the Encoding, Formatter, Level
> attributes of the ConsoleHandler, FileHandler services?

utf-8, an instance of the PlainTextFormatter, and LogLevel::SEVERE.
Added this to the service documentations.

> (The
> ConsoleHandler curiously uses a component context value to override the
> Level, instead of a constructor argument

No, the context value is used to determine the threshold: all events
with a level higher or equal to this threshold are written to stderr,
all below to stdout. This is different from the Level attribute, which
determines which events are completely discarded and not logged at all.

I consider the threshold to be too unimportant (read: too seldom to
change) to make it a ctor argument.

> , and instead of having this
> consistent across attributes and services.)

Hmm, what do you mean with "consistent across attributes and services"?
Introducing an XConsoleHandler with an attribute Threshold?

Also, please note that the XLogHandler documentation already asks
services implementing this interface to look for the initial
Encoding/Formatter/Level values in the context. So in some sense, the
ConsoleHandler is consistent with the interface it implements.

Basically, there are two reasons why I chose this context-based
initialization:

First, it's again similar to the Java API, which also allows retrieving
default values from various sources (see the LogManager documentation).

Second, it allows me to put a nice configuration-based initialization
mechanism in place :), where for a given named logger, the user can
configure initial settings (abstract name-value pairs, as far as the
configuration and the code reading it are concerned) for a handler,
which at instantiation time are used as context values.

> - LogRecord members SourceClassName, SourceMethodName (and XLogger.logp
> parameters SourceClass, SourceMethod, curiously with different names):

You're right, I changed the parameter names to equal the member names.

> If at the level of UNO, class does not make sense.  If at the level of
> implementation, neither class nor method make sense in general.

Not sure I get you here - for nearly all our language bindings those
concepts in fact exist.

Do you suggest getting rid of logp completely? Should "Class" be renamed
to "Component"? Should logp get a documentation that it might not make
sense in all implementations?

> - LogRecord member ThreadID:  UNO's notion of threads is rather
> abstract, there is no universal concept of mapping threads to hyper
> values.  (URP uses a mapping from threads to strings.)

Well, all platforms on which the URE runs have a mapping from threads to
hypers (vulgo: thread IDs), haven't they? I consider the thread ID a
highly useful information in some situations, so I would not really like
to remove it just because UNO so far has no concept for denoting a thread.

Should the thread ID be a string instead, and callers be responsible for
formatting the thread ID as string?

Thanks & Ciao
Frank

--
- Frank Schönheit, Software Engineer         [hidden email] -
- Sun Microsystems                      http://www.sun.com/staroffice -
- OpenOffice.org Base                       http://dba.openoffice.org -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

---------------------------------------------------------------------
To unsubscribe, e-mail: [hidden email]
For additional commands, e-mail: [hidden email]

Reply | Threaded
Open this post in threaded view
|

Re: UNO Logging API

stephan.bergmann
In reply to this post by frank.schoenheit
Frank Schönheit - Sun Microsystems Germany wrote:

> Hi Stephan,
>
>> - Should not the singleton be called "theLoggerPool" instead of
>> "LoggerPool"?
>
> A singleton I introduced to this list some time ago (IIRC, it was the
> OfficeResourceManager) used the same naming scheme. At this time, you
> asked the same question, but we agreed that it's not strictly necessary
> to use the "theFoo" scheme at this time. (Or, more precise, the question
> whether we should get rid of the "theFoo" convention was not answered.)
> This time, I hope to yak you down^W^W^Wconvince you again.

Oops, will try to remember next time.

>> - Is the LoggerPool overkill?
>
> no, IMO.
>
>> (Why not theDefaultLogger as a singleton
>> and arbitrarily named loggers as services?)
>
> Since named loggers as services would give you less freedom (read: more
> work) in "introducing" a new logger. With the current way, you can
> simply ask the pool for a logger with a given name. Otherwise, you would
> need to explicitly define/implement your new logger service.

But in your scheme the work is with the producer of the new logger, too!
  You need to register it.  (When is that done?)

>> - What are the initial values of the Encoding, Formatter, Level
>> attributes of the ConsoleHandler, FileHandler services?
>
> utf-8, an instance of the PlainTextFormatter, and LogLevel::SEVERE.
> Added this to the service documentations.
>
>> (The
>> ConsoleHandler curiously uses a component context value to override the
>> Level, instead of a constructor argument
>
> No, the context value is used to determine the threshold: all events
> with a level higher or equal to this threshold are written to stderr,
> all below to stdout. This is different from the Level attribute, which
> determines which events are completely discarded and not logged at all.
>
> I consider the threshold to be too unimportant (read: too seldom to
> change) to make it a ctor argument.

Hm, still looks hacky to me.  (Maybe its a hint that different handlers
have different parameters, so its not optimal to have that fixed set of
attributes at the common interface.  Encoding is also not universally used.)

>> , and instead of having this
>> consistent across attributes and services.)
>
> Hmm, what do you mean with "consistent across attributes and services"?

I meant it like "all parameters of all handlers, or none at all, treated
as attributes."

> Introducing an XConsoleHandler with an attribute Threshold?
>
> Also, please note that the XLogHandler documentation already asks
> services implementing this interface to look for the initial
> Encoding/Formatter/Level values in the context. So in some sense, the
> ConsoleHandler is consistent with the interface it implements.
>
> Basically, there are two reasons why I chose this context-based
> initialization:
>
> First, it's again similar to the Java API, which also allows retrieving
> default values from various sources (see the LogManager documentation).
>
> Second, it allows me to put a nice configuration-based initialization
> mechanism in place :), where for a given named logger, the user can
> configure initial settings (abstract name-value pairs, as far as the
> configuration and the code reading it are concerned) for a handler,
> which at instantiation time are used as context values.

Ah, the registry of available named loggers is configuration based (had
slipped me if it was already mentioned).  Still, parameters could be
passed generically via XInitialization instead of the component context.

>> - LogRecord members SourceClassName, SourceMethodName (and XLogger.logp
>> parameters SourceClass, SourceMethod, curiously with different names):
>
> You're right, I changed the parameter names to equal the member names.
>
>> If at the level of UNO, class does not make sense.  If at the level of
>> implementation, neither class nor method make sense in general.
>
> Not sure I get you here - for nearly all our language bindings those
> concepts in fact exist.

By coincidence.  As of today.

> Do you suggest getting rid of logp completely? Should "Class" be renamed
> to "Component"? Should logp get a documentation that it might not make
> sense in all implementations?

Would it make sense to replace class+method with a generic "context"
string, to be freely used by clients to put into it whatever they think
is relevant?

>> - LogRecord member ThreadID:  UNO's notion of threads is rather
>> abstract, there is no universal concept of mapping threads to hyper
>> values.  (URP uses a mapping from threads to strings.)
>
> Well, all platforms on which the URE runs have a mapping from threads to
> hypers (vulgo: thread IDs), haven't they? I consider the thread ID a
> highly useful information in some situations, so I would not really like
> to remove it just because UNO so far has no concept for denoting a thread.

(Not true for Java 1.4; java.lang.Thread.getId was introduced in Java 1.5.)

But those IDs can be rather meaningless for users, since they differ for
a single UNO thread, depending on which language binding you are in.

> Should the thread ID be a string instead, and callers be responsible for
> formatting the thread ID as string?

Why the callers?  We could lift UNO thread IDs (which are strings) from
a UNO implementation detail to proper citizens of the UNO environment,
so the code that fills in a LogRecord could obtain such a thread ID.

-Stephan

---------------------------------------------------------------------
To unsubscribe, e-mail: [hidden email]
For additional commands, e-mail: [hidden email]

Reply | Threaded
Open this post in threaded view
|

Re: UNO Logging API

frank.schoenheit
Hi Stephan,

>> Since named loggers as services would give you less freedom (read: more
>> work) in "introducing" a new logger. With the current way, you can
>> simply ask the pool for a logger with a given name. Otherwise, you would
>> need to explicitly define/implement your new logger service.
>
> But in your scheme the work is with the producer of the new logger, too!
>   You need to register it.  (When is that done?)

No, you just ask the pool for a logger with the given name. If it does
not (yet/anymore) exist, it will be created and returned. No overhead
anywhere, IMO.

>> No, the context value is used to determine the threshold: all events
>> with a level higher or equal to this threshold are written to stderr,
>> all below to stdout. This is different from the Level attribute, which
>> determines which events are completely discarded and not logged at all.
>>
>> I consider the threshold to be too unimportant (read: too seldom to
>> change) to make it a ctor argument.
>
> Hm, still looks hacky to me.  (Maybe its a hint that different handlers
> have different parameters, so its not optimal to have that fixed set of
> attributes at the common interface.  Encoding is also not universally used.)

No sure. The alternative would be something like

  XHandlerWithEncoding : XLogHandler
  {
    [attribute] string Encoding;
  };

  FileHandler : XHandlerWithEncoding ...

  XConsoleHandler : XHandlerWithEncoding
  {
    [attribute] int Threshold;
  }

,  which looks like overkill to me.

>> Second, it allows me to put a nice configuration-based initialization
>> mechanism in place :), where for a given named logger, the user can
>> configure initial settings (abstract name-value pairs, as far as the
>> configuration and the code reading it are concerned) for a handler,
>> which at instantiation time are used as context values.
>
> Ah, the registry of available named loggers is configuration based (had
> slipped me if it was already mentioned).

No, not mentioned. Intentionally, since I am not sure whether this
really belongs into the API definition, especially since those APIs
originally were part of the URE (udkapi, meanwhile I moved them to
offapi as per your suggestion), and I don't think that talking about
OOo's configuration would a good idea in the URE - wouldn't it?

> Still, parameters could be
> passed generically via XInitialization instead of the component context.

Given that XInitialization is (mis)used for constructor initialization
as of today, this would imply that a handler service could either have
one or more constructors, or allow for attribute initialization, but not
both. Else, every possible combination of to-be-initialized attributes
would need to be mapped to a constructor, which would soon let the ctor
count explode. Or the ::initialize implementation would need to apply
some magic to determine whether it's called as part of the constructor
implementation, or as initialization.

Don't really like this idea, sorry.

(Yes, don't *really* like the context value idea, too. But it seemed the
one with the least disadvantages.)

>> Do you suggest getting rid of logp completely? Should "Class" be renamed
>> to "Component"? Should logp get a documentation that it might not make
>> sense in all implementations?
>
> Would it make sense to replace class+method with a generic "context"
> string, to be freely used by clients to put into it whatever they think
> is relevant?

Hmm, this could do.

>>> - LogRecord member ThreadID:  UNO's notion of threads is rather
>>> abstract, there is no universal concept of mapping threads to hyper
>>> values.  (URP uses a mapping from threads to strings.)
>> Well, all platforms on which the URE runs have a mapping from threads to
>> hypers (vulgo: thread IDs), haven't they? I consider the thread ID a
>> highly useful information in some situations, so I would not really like
>> to remove it just because UNO so far has no concept for denoting a thread.
>
> (Not true for Java 1.4; java.lang.Thread.getId was introduced in Java 1.5.)

Lemme be nitpicking, please ;)
The LogRecord - part of the Java logging API since 1.4 - has a member
ThreadID. So, the *concept* of a thread ID existed before there was a
possibility to obtain it from a Thread object ...

> But those IDs can be rather meaningless for users, since they differ for
> a single UNO thread, depending on which language binding you are in.

That's true in some cases. However, when it comes to adding log code to
a component which is written in C++, as is the logger, then the ID has a
meaning. And the IDs might provide useful information in those cases.

>> Should the thread ID be a string instead, and callers be responsible for
>> formatting the thread ID as string?
>
> Why the callers?  We could lift UNO thread IDs (which are strings) from
> a UNO implementation detail to proper citizens of the UNO environment,
> so the code that fills in a LogRecord could obtain such a thread ID.

Okay, how would this lifting look like? Simply declaring
LogRecord.ThreadID as string probably isn't sufficient?

Thanks & Ciao
Frank

--
- Frank Schönheit, Software Engineer         [hidden email] -
- Sun Microsystems                      http://www.sun.com/staroffice -
- OpenOffice.org Base                       http://dba.openoffice.org -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

---------------------------------------------------------------------
To unsubscribe, e-mail: [hidden email]
For additional commands, e-mail: [hidden email]

Reply | Threaded
Open this post in threaded view
|

Re: UNO Logging API

stephan.bergmann
In reply to this post by frank.schoenheit
Frank Schönheit - Sun Microsystems Germany wrote:

> Hi Stephan,
>
>>> Since named loggers as services would give you less freedom (read: more
>>> work) in "introducing" a new logger. With the current way, you can
>>> simply ask the pool for a logger with a given name. Otherwise, you would
>>> need to explicitly define/implement your new logger service.
>> But in your scheme the work is with the producer of the new logger, too!
>>   You need to register it.  (When is that done?)
>
> No, you just ask the pool for a logger with the given name. If it does
> not (yet/anymore) exist, it will be created and returned. No overhead
> anywhere, IMO.

I fear I do not get you.  What kind of logger is "created and returned"?
  A generic one, probably.  How does client code use it?  It has to
check whether the logger already has some log handlers added or not, add
some if necessary.  Sounds strange.

[...]

>> Still, parameters could be
>> passed generically via XInitialization instead of the component context.
>
> Given that XInitialization is (mis)used for constructor initialization
> as of today, this would imply that a handler service could either have
> one or more constructors, or allow for attribute initialization, but not
> both. Else, every possible combination of to-be-initialized attributes
> would need to be mapped to a constructor, which would soon let the ctor
> count explode. Or the ::initialize implementation would need to apply
> some magic to determine whether it's called as part of the constructor
> implementation, or as initialization.

Yes, XInitialization behind the scenes of service constructors is a bad
hack (that will hopefully go away).  However, it should not be too hard
to write a service implementation for a service like

   service ConsoleHandler: XLogHandler {
     specific([in] string encoding, [in] XLogFormatter formatter, [in]
long level, [in] long threshold);
     generic([in] sequence<PropertyValue> arguments) raises
(IllegalArgumentException);
   };

which could then nicely be called through a generic
createInstanceWithArguments (and should define a reasonable policy how
to handle missing and excess arguments).

[...]

>>>> - LogRecord member ThreadID:  UNO's notion of threads is rather
>>>> abstract, there is no universal concept of mapping threads to hyper
>>>> values.  (URP uses a mapping from threads to strings.)
>>> Well, all platforms on which the URE runs have a mapping from threads to
>>> hypers (vulgo: thread IDs), haven't they? I consider the thread ID a
>>> highly useful information in some situations, so I would not really like
>>> to remove it just because UNO so far has no concept for denoting a thread.
>> (Not true for Java 1.4; java.lang.Thread.getId was introduced in Java 1.5.)
>
> Lemme be nitpicking, please ;)
> The LogRecord - part of the Java logging API since 1.4 - has a member
> ThreadID. So, the *concept* of a thread ID existed before there was a
> possibility to obtain it from a Thread object ...

And how would that help us to implement a LogRecord filler that is
compatible with Java 1.3.1 (or current base line)?

[...]
>>> Should the thread ID be a string instead, and callers be responsible for
>>> formatting the thread ID as string?
>> Why the callers?  We could lift UNO thread IDs (which are strings) from
>> a UNO implementation detail to proper citizens of the UNO environment,
>> so the code that fills in a LogRecord could obtain such a thread ID.
>
> Okay, how would this lifting look like? Simply declaring
> LogRecord.ThreadID as string probably isn't sufficient?

Functionality that allows client code to obtain the ID of the UNO thread
it is executing in would have to be offered in the interface of each UNO
language binding.  (The functionality should generally be already there,
just not officially offered to client code.)

> Thanks & Ciao
> Frank

---------------------------------------------------------------------
To unsubscribe, e-mail: [hidden email]
For additional commands, e-mail: [hidden email]

Reply | Threaded
Open this post in threaded view
|

Re: UNO Logging API

frank.schoenheit
Hi Stephan,

>>>But in your scheme the work is with the producer of the new logger, too!
>>>  You need to register it.  (When is that done?)
>>No, you just ask the pool for a logger with the given name. If it does
>>not (yet/anymore) exist, it will be created and returned. No overhead
>>anywhere, IMO.
>
> I fear I do not get you.  What kind of logger is "created and returned"?
>   A generic one, probably.  How does client code use it?  It has to
> check whether the logger already has some log handlers added or not, add
> some if necessary.

Okay, perhaps I really should make the documentation about the
configuration-based initialization part of the IDLs ...

Current state by implementation is that a newly created logger has a
file handler associated with it, which writes to
$(userurl)/$(loggername).log. With this, a component which wants to log
something can simply do a
  logger = LoggerPool.get().getLogger( <specificName> );
  logger.log( ... )


Other than that, I'd expect loggers to be "module"-specific (where I use
"module" denoting a collection of components semantically coupled. For
instances, all components contributing to Base' JDBC driver
implementation would be a "module".). A dedicated instance within a
component would create and initalize the logger with a
component-specific name, all other parts of the module would only
instantiate the logger.

> Yes, XInitialization behind the scenes of service constructors is a bad
> hack (that will hopefully go away).  However, it should not be too hard
> to write a service implementation for a service like
>
>    service ConsoleHandler: XLogHandler {
>      specific([in] string encoding, [in] XLogFormatter formatter, [in]
> long level, [in] long threshold);
>      generic([in] sequence<PropertyValue> arguments) raises
> (IllegalArgumentException);
>    };
>
> which could then nicely be called through a generic
> createInstanceWithArguments (and should define a reasonable policy how
> to handle missing and excess arguments).

Uh - createInstanceWithArguments currently also uses XInitialization,
but this is an implementation detail of the respective factories only.
(I remember that long ago, we implemented factories for the
configuration provider which in fact did something different.)

So no, createInstanceWithArguments is not an option here, since it would
assume that constructors are implemented using XInitialization, and thus
cement this hack for all time.

However, looking at XServiceDescription2 ... I did not try it, but this
looks indeed as if a generic handler instantiation code could check
whether the to-be-instantiated service supports a ctor taking a
sequence<PropertyValue> (btw. I definatily prefer NamedValue here and it
all similar cases, using PropertyValue is an unnecessary hack since we
have NamedValues.).

Assuming that the initialization happens using name-value pairs, it is
even possible to look for a ctor taking arguments with the proper
names/types in any order ...

Hmm, sounds tempting from an architectural point of view, but not really
like fun implementing it :-\

Assuming a proper ctor is found, how can I generically invoke it
(*without* using XInitialization directly)?

>>>(Not true for Java 1.4; java.lang.Thread.getId was introduced in Java 1.5.)
>>
>>Lemme be nitpicking, please ;)
>>The LogRecord - part of the Java logging API since 1.4 - has a member
>>ThreadID. So, the *concept* of a thread ID existed before there was a
>>possibility to obtain it from a Thread object ...
>
> And how would that help us to implement a LogRecord filler that is
> compatible with Java 1.3.1 (or current base line)?

Hmm, yes, it wouldn't. But before somebody implements a logger in Java
1.3.1 (instead of using the existing implementation which doesn't have
this problem), Java 1.4 is the base line :).

The more since a Java logger implementation doesn't make any sense,
since here the ThreadID becomes meaningless, anyway - the Java UNO
bridge doesn't "preserve" the thread of the caller, as far as I know, so
every Java implementation obtaining the ThreadID would fill in nonsense.

> Functionality that allows client code to obtain the ID of the UNO thread
> it is executing in would have to be offered in the interface of each UNO
> language binding.  (The functionality should generally be already there,
> just not officially offered to client code.)

Okay, so I'll make the ID a string, and for the moment fill it by
converting the numerical ID to a string myself. I'll then file an issue
(to you?) requesting the functionality you describe.


Overall, this leaves us with the following items
- make ThreadID a string
- document the configuration-based initialization pattern
- initialize via ctor using reflection, not context values
  (assuming that a ctor can generically be called)

Did I forget something?

Thanks & Ciao
Frank

---------------------------------------------------------------------
To unsubscribe, e-mail: [hidden email]
For additional commands, e-mail: [hidden email]

Reply | Threaded
Open this post in threaded view
|

Re: UNO Logging API

stephan.bergmann
In reply to this post by frank.schoenheit
Frank Schönheit wrote:
[...]

>> Yes, XInitialization behind the scenes of service constructors is a bad
>> hack (that will hopefully go away).  However, it should not be too hard
>> to write a service implementation for a service like
>>
>>    service ConsoleHandler: XLogHandler {
>>      specific([in] string encoding, [in] XLogFormatter formatter, [in]
>> long level, [in] long threshold);
>>      generic([in] sequence<PropertyValue> arguments) raises
>> (IllegalArgumentException);
>>    };
>>
>> which could then nicely be called through a generic
>> createInstanceWithArguments (and should define a reasonable policy how
>> to handle missing and excess arguments).
>
> Uh - createInstanceWithArguments currently also uses XInitialization,
> but this is an implementation detail of the respective factories only.
> (I remember that long ago, we implemented factories for the
> configuration provider which in fact did something different.)
>
> So no, createInstanceWithArguments is not an option here, since it would
> assume that constructors are implemented using XInitialization, and thus
> cement this hack for all time.

Why?  Today, service ctors are internally calling
createInstanceWithArguments, and createInstanceWithArguments internally
calls XInitialization.

createInstanceWithArguments to create a service can probably never go
away, for backwards compatibility reasons.

So, whatever service ctors are going to do internally in the future, we
should better define how service ctors and createInstanceWithArguments
are conceptually intended to play together.  That is, how
createInstanceWithArguments can be interpreted in terms of service
ctors.  There are three cases to consider:

1  New-style services with a default ctor.  The default ctor has
signature ([in] any... arguments), which matches nicely with the
createInstanceWithArguments([in] sequence<any> arguments) signature.

2  New-style services with no ctor, and old-style services.  These
anyway rely on being created with createInstanceWithArguments.

3  New-style services with one or more explicit ctors.  (The current
limitation for those ctors is that their signatures are sufficiently
different, so that a service implementation can distinguish ctor calls
based on the arguments passed in via createInstanceWithArguments.  This
limitation should fall in the future.)  I would suggest the following:
If among the ctors there is exactly one with signature ([in] any...),
calling createInstanceWithArguments calls that ctor; otherwise, calling
createInstanceWithArguments has unspecified results.

That would mean that we would have to revert to weaker typing for the
ConsoleHandler service above:

    service ConsoleHandler: XLogHandler {
      specific([in] string encoding, [in] XLogFormatter formatter, [in]
long level, [in] long threshold);
      generic([in] any... arguments) raises (IllegalArgumentException);
// arguments must be of type NamedValue
    };

You implement a ConsoleHandler with XInitialize (having to check whether
the argument sequence is either <string, XLogFormatter, long, long> or
<NamedValue...>).  You generically instantiate handler services with
createInstanceWithArguments, and we are guaranteed that this will
continue to work, even with future handler services, as long as all
handler services are defined to have one ctor with ([in] any...)
signature.  No need for XServiceDescription2 reflection.

> However, looking at XServiceDescription2 ... I did not try it, but this
> looks indeed as if a generic handler instantiation code could check
> whether the to-be-instantiated service supports a ctor taking a
> sequence<PropertyValue> (btw. I definatily prefer NamedValue here and it
> all similar cases, using PropertyValue is an unnecessary hack since we
> have NamedValues.).

NamedValue vs. PropertyValue:  Yes, NamedValue was what I had in mind
(just could not remember its name).

> Assuming that the initialization happens using name-value pairs, it is
> even possible to look for a ctor taking arguments with the proper
> names/types in any order ...
>
> Hmm, sounds tempting from an architectural point of view, but not really
> like fun implementing it :-\
>
> Assuming a proper ctor is found, how can I generically invoke it
> (*without* using XInitialization directly)?
>
>>>> (Not true for Java 1.4; java.lang.Thread.getId was introduced in Java 1.5.)
>>> Lemme be nitpicking, please ;)
>>> The LogRecord - part of the Java logging API since 1.4 - has a member
>>> ThreadID. So, the *concept* of a thread ID existed before there was a
>>> possibility to obtain it from a Thread object ...
>> And how would that help us to implement a LogRecord filler that is
>> compatible with Java 1.3.1 (or current base line)?
>
> Hmm, yes, it wouldn't. But before somebody implements a logger in Java
> 1.3.1 (instead of using the existing implementation which doesn't have
> this problem), Java 1.4 is the base line :).
>
> The more since a Java logger implementation doesn't make any sense,
> since here the ThreadID becomes meaningless, anyway - the Java UNO
> bridge doesn't "preserve" the thread of the caller, as far as I know, so
> every Java implementation obtaining the ThreadID would fill in nonsense.

But client code calling the logger should/could not be aware whether
access to the logger is bridged, and any language-binding--specific
thread IDs filled in by the logger would thus be meaningful from the
client's point of view.  That's why I argue for using
language-binding--independent UNO thread IDs (which are strings) instead
of langugage-binding--specific thread IDs (which are typically some
integers).

>> Functionality that allows client code to obtain the ID of the UNO thread
>> it is executing in would have to be offered in the interface of each UNO
>> language binding.  (The functionality should generally be already there,
>> just not officially offered to client code.)
>
> Okay, so I'll make the ID a string, and for the moment fill it by
> converting the numerical ID to a string myself. I'll then file an issue
> (to you?) requesting the functionality you describe.

For the C++ UNO language binding, the functionality is already
available, albeit in a crude way: uno_getIdOfCurrentThread
(uno/threadpool.h, from cppu) gives the thread ID in the form of a byte
sequence (thread IDs are really byte sequences, not strings, see section
"Threads" of <http://udk.openoffice.org/common/man/spec/urp.html>; I had
forgotten about that detail).  For an "official" way to produce UNO
string representations of thread IDs, I would suggest to interpret each
individual byte 0xXX as an individual Unicode scalar value U+00XX (i.e.,
interpret the byte sequence as an ISO-8859-1 string and translate it
into a UNO string).  Independent of that, please file an issue for an
appropriate API.

> Overall, this leaves us with the following items
> - make ThreadID a string
> - document the configuration-based initialization pattern
> - initialize via ctor using reflection, not context values
>   (assuming that a ctor can generically be called)
>
> Did I forget something?
>
> Thanks & Ciao
> Frank

-Stephan

---------------------------------------------------------------------
To unsubscribe, e-mail: [hidden email]
For additional commands, e-mail: [hidden email]

Reply | Threaded
Open this post in threaded view
|

Re: UNO Logging API

frank.schoenheit
Hi Stephan,

back to this topic after quite a while ...

>>- make ThreadID a string

Done. Also submitted an issue requesting an official way to retrieve the
UNO Thread ID, assigned to you.

>>- document the configuration-based initialization pattern

Done.

>>- initialize via ctor using reflection, not context values
>>  (assuming that a ctor can generically be called)

Changed so that the initialization now happens using a generic constructor
  createWithSettings( [in] sequence< NamedValue > Settings );

Ciao
Frank

--
- Frank Schönheit, Software Engineer         [hidden email] -
- Sun Microsystems                      http://www.sun.com/staroffice -
- OpenOffice.org Base                       http://dba.openoffice.org -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

---------------------------------------------------------------------
To unsubscribe, e-mail: [hidden email]
For additional commands, e-mail: [hidden email]

Reply | Threaded
Open this post in threaded view
|

Re: UNO Logging API

frank.schoenheit
In reply to this post by frank.schoenheit
> Overall, this leaves us with the following items
> - make ThreadID a string
> - document the configuration-based initialization pattern
> - initialize via ctor using reflection, not context values
>   (assuming that a ctor can generically be called)
>
> Did I forget something?

Now that I wrote the API changes mails I noticed I *did* forget
something: Didn't we talk about changing the class/method parameters to
something else ...?

Hmm, this will have to wait for a new CWS, I fear ...

Ciao
Frank

--
- Frank Schönheit, Software Engineer         [hidden email] -
- Sun Microsystems                      http://www.sun.com/staroffice -
- OpenOffice.org Base                       http://dba.openoffice.org -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

---------------------------------------------------------------------
To unsubscribe, e-mail: [hidden email]
For additional commands, e-mail: [hidden email]