Re: New API for log level manipulation
> On Nov 2, 2024, at 3:51 PM, Piotr P. Karwasz > wrote: > > This would be the same setting as in Commons Logging, so I guess I would be > OK with that, if we keep an extension mechanism in the API. We could probably > split the implementation in two parts: Log4j Core can receive his > implementation, while Logback and JUL will be integrated in an internal > package of the API (so we can remove them later). > > Once we smooth the API (naming, naming and again naming ;-) ), I can ping > Ceki and see if he is willing to adopt it in Logback. Potentially there are a > lot of places, where the API could replace logging implementation specific > code ([1] and [2]). I pretty much doubt that those projects have both an > implementation for Log4j Core and Logback. I think you missed my point. I don’t think Log4j-core, Logback or whatever should need to implement anything. The point of such an API is to provide a standard API that implements whatever is necessary to perform the action. i.e. in Log4j’s case setLEvel would call Configurator.setLevel. Ralph
Re: New API for log level manipulation
Hi Ralph, On 2.11.2024 22:48, Ralph Goers wrote: 1. getLoggerContext returns a meaningless object. The object returned only has value if you know what it is and if you do then you might as well be tied to whatever the implementation is. 2. You are passing in an arbitrary parameter to getInstance(). In reality you would have to know what the object should be for the implementation you are using. These two methods are part of the "locking" mechanism and they could certainly be refactored in a more meaningful way. The object passed to `getInstance` can be any Java object. Its purpose is only to prevent access to the API to all subsequent callers that do not own the object. An example of usage: private static final Object LOGGING_ADMIN_TOKEN = new Object(); private final LoggingConfigurationAdmin = LoggingConfigurationAdmin.getInstance(LOGGING_ADMIN_TOKEN); The `getLoggerContext` method is only used internally, so that implementations can tell which "logger context" has been locked. Internally there is a map "logger context -> security token" that is used to prevent unauthorized access.À priori I assumed that in a multi-user environment, each application can configure its own logging subsystem. 3. The only thing of real value you are getting out of this are the “Level” methods. Yes, this is the main purpose of the API. I would think this would have to live in its own repo. It should be able to support Logback, Log4j-Core, and JuL simply by checking which is present. In other words, the API and the implementation would all reside together in one jar. I know you hate doing that but anything else is overkill iMO. This would be the same setting as in Commons Logging, so I guess I would be OK with that, if we keep an extension mechanism in the API. We could probably split the implementation in two parts: Log4j Core can receive his implementation, while Logback and JUL will be integrated in an internal package of the API (so we can remove them later). Once we smooth the API (naming, naming and again naming ;-) ), I can ping Ceki and see if he is willing to adopt it in Logback. Potentially there are a lot of places, where the API could replace logging implementation specific code ([1] and [2]). I pretty much doubt that those projects have both an implementation for Log4j Core and Logback. Piotr [1] https://github.com/search?q=LogManager.getContext%28false%29&type=code [2] https://github.com/search?q=LoggerFactory.getILoggerFactory%28%29&type=code
Re: New API for log level manipulation
Hi Gary, On 2.11.2024 23:14, Gary D. Gregory wrote: In general, talking about API signatures without (pseudo)-Javadoc is not great, there is too much wrong for miscommunication or plain old guesing. FWIW, the JavaDoc is there in my repo[1] together with a short README[2]. I only removed it to shorten my post to `dev@logging`. [1] https://github.com/ppkarwasz/logging-admin/blob/main/api/src/main/java/org/apache/logging/admin/LoggingConfigurationAdmin.java [2] https://github.com/ppkarwasz/logging-admin/blob/main/README.adoc static LoggingConfigurationAdmin getInstance(Object token, ClassLoader classLoader); static LoggingConfigurationAdmin getInstance(Object token); Why do I need those AND getLoggerContext()? I though the point of this interface was a one-stop-shop. What's LoggingConfigurationAdmin doing for me? ... 2. How do we prevent users from abusing this API? You don't. Or, you don't deliver the JAR with your app. You can't stop users from hacking, formally or informally. Reflection is always around the corner to boot. The `token` parameter of `getInstance` is my attempt to limit the abuse of the API, by limiting the access to each logger context to the code that has access to `token`. This is currently done on a per-logger context level, which might explain the `getLoggerContext` method (used internally). Sure, we can not count on a bullet proof mechanism that prevents multiple entities from modifying the logger configuration, but we could develop a mechanism of discretionary access control. Currently Spring Boot modifies the logging configuration even if it is running in a Servlet Container with a single Logger Context. We could provide some methods that inform Spring Boot of this fact. 4. What should be the lifecycle of this API and where should it live? KISS 101: Not ANOTHER repo and version numbering system. Match Log4j and be done with it. Unless... you want to make this a new component as a sibling to Apache Logging Services Log4j: Apache Logging Services Admin. I guess I want to make this a sibling project. Once I have integrated all the feedback you have given into the draft, I can create a `logging-admin` repo and we can discuss the details in PRs. Piotr
Re: New API for log level manipulation
Hi all, On 31.10.2024 16:11, Piotr P. Karwasz wrote: Currently we have `o.a.l.l.c.config.Configurator` that allows level manipulation, but this is a Log4j Core specific class, which only works with Log4j Core. We could publish a small API (e.g. called LogAdmin) that allows to: * list the configured level of all loggers, * get the configured level of a single logger, * set the configured level of a single logger. I have attempted a first sketch of the Apache Logging Admin API in my personal repo[1], which ended up having the following methods (the Javadoc is in the repo): public interface LoggingConfigurationAdmin { Object getLoggerContext(); Set getSupportedLevels(); Map> getLoggerLevels(); Optional getLoggerLevel(String loggerName); void setLoggerLevel(String loggerName, @Nullable String level); static LoggingConfigurationAdmin getInstance(Object token, ClassLoader classLoader); static LoggingConfigurationAdmin getInstance(Object token); } While the implementation is rather straightforward, there are some aspects we should think about: 1. How should this API be called? I think that the name should NOT contain "Log4j", which would cause the same confusion as with Log4j API. Users would assume that the API only works with Log4j Core. 2. How do we prevent users from abusing this API? I call "abuse" the kind of help some libraries provide to application developers, by "improving" the logging configuration behind the application developer's back. As an attempt to solve this problem I added a "security token" to the `getInstance` method. It works like the token used in Tomcat's JNDI implementation[2]: the first caller chooses the token, all subsequent calls to `getInstance` must provide the same token. 3. Should we provide some parameters (in the example above `ClassLoader`) to help implementations choose the correct logger context to modify? Only the Log4j API offers such a parameter to retrieve the appropriate `LoggerContext` and in practice the parameter is only used by `ClassLoaderContextSelector`, which usually infers the value of the parameter anyway. 4. What should be the lifecycle of this API and where should it live? I would prefer to keep it in a separate repo, with a separate lifecycle (start with version `0.1.0`, so we can make breaking changes in the incubating phase) and possibly use a different Maven `groupId` (e.g. `org.apache.logging.admin`). 5. Where should the implementations of this API live? It would be nice to add implementations of this API directly to the logging implementation artifacts (Log4j Core and Logback), but there is a JPMS catch: if a JPMS module exports a service, the dependency that defines the service type can NOT be optional! Therefore Log4j Core (and maybe Logback) would need to have a hard dependency on this API. What do you think? Piotr [1] https://github.com/ppkarwasz/logging-admin [2] https://tomcat.apache.org/tomcat-11.0-doc/api/org/apache/naming/ContextBindings.html
Re: New API for log level manipulation
Hi Piotr, In general, talking about API signatures without (pseudo)-Javadoc is not great, there is too much wrong for miscommunication or plain old guesing. > Set getSupportedLevels(); It is not helpful to return a set IMO . This should be a list in a documented order from one min or max level of specificity to the other end. > Object getLoggerContext(); Returning Object is not helpful but I don't know how to solve that or if the API is needed at all. I'm not a fan of Optional in general FWIW. > Optional getLoggerLevel(String loggerName); > void setLoggerLevel(String loggerName, @Nullable String level); Since you can only set the level on a Logger, using "Logger" in the API names is superfluous. > static LoggingConfigurationAdmin getInstance(Object token, > ClassLoader classLoader); > static LoggingConfigurationAdmin getInstance(Object token); Why do I need those AND getLoggerContext()? I though the point of this interface was a one-stop-shop. What's LoggingConfigurationAdmin doing for me? > 1. How should this API be called? I think that the name should NOT > contain "Log4j", which would cause the same confusion as with Log4j API. > Users would assume that the API only works with Log4j Core. Do you mean the Maven artifact ID? How about "logging-admin"? > 2. How do we prevent users from abusing this API? You don't. Or, you don't deliver the JAR with your app. You can't stop users from hacking, formally or informally. Reflection is always around the corner to boot. > 4. What should be the lifecycle of this API and where should it live? KISS 101: Not ANOTHER repo and version numbering system. Match Log4j and be done with it. Unless... you want to make this a new component as a sibling to Apache Logging Services Log4j: Apache Logging Services Admin. HTH, Gary On 2024/11/02 19:42:15 "Piotr P. Karwasz" wrote: > Hi all, > > On 31.10.2024 16:11, Piotr P. Karwasz wrote: > > Currently we have `o.a.l.l.c.config.Configurator` that allows level > > manipulation, but this is a Log4j Core specific class, which only > > works with Log4j Core. We could publish a small API (e.g. called > > LogAdmin) that allows to: > > > > * list the configured level of all loggers, > > > > * get the configured level of a single logger, > > > > * set the configured level of a single logger. > > > I have attempted a first sketch of the Apache Logging Admin API in my > personal repo[1], which ended up having the following methods (the > Javadoc is in the repo): > > public interface LoggingConfigurationAdmin { > Object getLoggerContext(); > Set getSupportedLevels(); > Map> getLoggerLevels(); > Optional getLoggerLevel(String loggerName); > void setLoggerLevel(String loggerName, @Nullable String level); > static LoggingConfigurationAdmin getInstance(Object token, > ClassLoader classLoader); > static LoggingConfigurationAdmin getInstance(Object token); > } > > While the implementation is rather straightforward, there are some > aspects we should think about: > > 1. How should this API be called? I think that the name should NOT > contain "Log4j", which would cause the same confusion as with Log4j API. > Users would assume that the API only works with Log4j Core. > > 2. How do we prevent users from abusing this API? I call "abuse" the > kind of help some libraries provide to application developers, by > "improving" the logging configuration behind the application developer's > back. As an attempt to solve this problem I added a "security token" to > the `getInstance` method. It works like the token used in Tomcat's JNDI > implementation[2]: the first caller chooses the token, all subsequent > calls to `getInstance` must provide the same token. > > 3. Should we provide some parameters (in the example above > `ClassLoader`) to help implementations choose the correct logger context > to modify? Only the Log4j API offers such a parameter to retrieve the > appropriate `LoggerContext` and in practice the parameter is only used > by `ClassLoaderContextSelector`, which usually infers the value of the > parameter anyway. > > 4. What should be the lifecycle of this API and where should it live? I > would prefer to keep it in a separate repo, with a separate lifecycle > (start with version `0.1.0`, so we can make breaking changes in the > incubating phase) and possibly use a different Maven `groupId` (e.g. > `org.apache.logging.admin`). > > 5. Where should the implementations of this API live? It would be nice > to add implementations of this API directly to the logging > implementation artifacts (Log4j Core and Logback), but there is a JPMS > catch: if a JPMS module exports a service, the dependency that defines > the service type can NOT be optional! Therefore Log4j Core (and maybe > Logback) would need to have a hard dependency on this API. > > What do you think? > > Piotr > > [1] https://github.com/ppkarwasz/logging-admin > > [2
Re: New API for log level manipulation
To be honest, I have never been a fan of this kind of interface because: 1. getLoggerContext returns a meaningless object. The object returned only has value if you know what it is and if you do then you might as well be tied to whatever the implementation is. 2. You are passing in an arbitrary parameter to getInstance(). In reality you would have to know what the object should be for the implementation you are using. 3. The only thing of real value you are getting out of this are the “Level” methods. I would think this would have to live in its own repo. It should be able to support Logback, Log4j-Core, and JuL simply by checking which is present. In other words, the API and the implementation would all reside together in one jar. I know you hate doing that but anything else is overkill iMO. Ralph > On Nov 2, 2024, at 12:42 PM, Piotr P. Karwasz > wrote: > > Hi all, > > On 31.10.2024 16:11, Piotr P. Karwasz wrote: >> Currently we have `o.a.l.l.c.config.Configurator` that allows level >> manipulation, but this is a Log4j Core specific class, which only works with >> Log4j Core. We could publish a small API (e.g. called LogAdmin) that allows >> to: >> >> * list the configured level of all loggers, >> >> * get the configured level of a single logger, >> >> * set the configured level of a single logger. >> > I have attempted a first sketch of the Apache Logging Admin API in my > personal repo[1], which ended up having the following methods (the Javadoc is > in the repo): > > public interface LoggingConfigurationAdmin { > Object getLoggerContext(); > Set getSupportedLevels(); > Map> getLoggerLevels(); > Optional getLoggerLevel(String loggerName); > void setLoggerLevel(String loggerName, @Nullable String level); > static LoggingConfigurationAdmin getInstance(Object token, ClassLoader > classLoader); > static LoggingConfigurationAdmin getInstance(Object token); > } > > While the implementation is rather straightforward, there are some aspects we > should think about: > > 1. How should this API be called? I think that the name should NOT contain > "Log4j", which would cause the same confusion as with Log4j API. Users would > assume that the API only works with Log4j Core. > > 2. How do we prevent users from abusing this API? I call "abuse" the kind of > help some libraries provide to application developers, by "improving" the > logging configuration behind the application developer's back. As an attempt > to solve this problem I added a "security token" to the `getInstance` method. > It works like the token used in Tomcat's JNDI implementation[2]: the first > caller chooses the token, all subsequent calls to `getInstance` must provide > the same token. > > 3. Should we provide some parameters (in the example above `ClassLoader`) to > help implementations choose the correct logger context to modify? Only the > Log4j API offers such a parameter to retrieve the appropriate `LoggerContext` > and in practice the parameter is only used by `ClassLoaderContextSelector`, > which usually infers the value of the parameter anyway. > > 4. What should be the lifecycle of this API and where should it live? I would > prefer to keep it in a separate repo, with a separate lifecycle (start with > version `0.1.0`, so we can make breaking changes in the incubating phase) and > possibly use a different Maven `groupId` (e.g. `org.apache.logging.admin`). > > 5. Where should the implementations of this API live? It would be nice to add > implementations of this API directly to the logging implementation artifacts > (Log4j Core and Logback), but there is a JPMS catch: if a JPMS module exports > a service, the dependency that defines the service type can NOT be optional! > Therefore Log4j Core (and maybe Logback) would need to have a hard dependency > on this API. > > What do you think? > > Piotr > > [1] https://github.com/ppkarwasz/logging-admin > > [2] > https://tomcat.apache.org/tomcat-11.0-doc/api/org/apache/naming/ContextBindings.html > >