Avaya Conferencinge Plugable Logging API

Avaya Conferencing Plugable Logging 6.2.0.0.38

Avaya Conferencing Plugable Logging

See:
          Description

Packages
com.avaya.conferencing.logging Provides the class and interfaces used to abstract logging.

 

Avaya Conferencing Plugable Logging

The Avaya Conferencing Plugable Logging API (or ACPL) is intended to serve as a facade for various logging APIs allowing end-users to plug in the desired implementation at deployment time.

Note: ACPL is not intended to be used as a general purpose logging framework.

Use cases

The following use cases illustrate how ACPL can be used.

Use-case #1

An application developer is developing an application. The application is using a specific logging framework (e.g. log4j, or commons-logging, java.util.logging). The application will use an Avaya Conferencing Java API (e.g. the Avaya Conferencing Provider Interface). ACPL allows the developer to direct the Avaya Conferencing Java API's logging through to the specific logging framework used by the application.

Use-case #2

An application developer maintaining an existing application which uses it's own custom in-house logging framework. The application is being extended to use an Avaya Conferencing Java API (e.g. the Avaya Conferencing Provider Interface). ACPL allows the developer to write an ACPL implementation that will direct the Avaya Conferencing Java API's logging through to the custom in-house logging framework used by the application.

Implementation

ACPL uses the Java Service Provider mechanism to find the implementation of LoggerManager to use.

The first time ACPL is invoked it will search the context class loader. If the context class loader is not defined it will fall back to the system class loader.

If no implementations are found, then ACPL will fall back to its default internal implementation which routes all logging through java.util.logging.

Note: If multiple implementations are found, then ACPL will pick the first one it finds (i.e. it will effectively pick one at random) and use that one.

Thus, if you want to use an Avaya Conferencing Java API with log4j your application classpath will require:

Alternatively, if you want to use an Avaya Conferencing Java API with commons-logging your application classpath will require:

Finally, if you want to use an Avaya Conferencing Java API with java.util.logging your application classpath will require:

Writing your own ACPL provider

If your application uses a custom in-house logging framework, you will need to write your own ACPL provider. An ACPL provider is a jar file that consists of:

Note: It is a convention that the ACPL provider jar does not contain the actual logging framework classes. For example acpl-log4j-x.y.z.w.v.jar does not include any of the log4j classes. This convention allows the ACPL provider to be loosely coupled with the logging framework that it uses.

Example implementation

The following is a bare bones implementation that sends Level.FATAL logging messages to System.err and discards all other logging messages

    /*
     * Copyright 2008-2009 Avaya Inc.
     *
     * Licensed under the Apache License, Version 2.0 (the "License");
     * you may not use this file except in compliance with the License.
     * You may obtain a copy of the License at
     *     http://www.apache.org/licenses/LICENSE-2.0
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     * See the License for the specific language governing permissions and
     * limitations under the License.
     *
     */
    package com.avaya.conferencing.logging.example;

    import java.text.MessageFormat;
    import java.util.ResourceBundle;
    import java.util.MissingResourceException;

    public class ExampleLoggerManager implements LoggerManager{

        public Logger getLogger(final Class sourceClass) {
            return new Logger(new LogWorker(){
                private final ResourceBundle messageBundle =
                        Logger.loadResourceBundle(sourceClass.getPackage().getName() + ".LogMessages");

                public String format(LogMessage message) {
                    if (messageBundle == null) {
                        return message.getKey();
                    }
                    try {
                        return messageBundle.getString(message.getKey());
                    } catch (MissingResourceException e) {
                        return message.getKey();
                    }
                }

                public String format(LogMessage message, Object arg1) {
                    return MessageFormat.format(format(message), arg1);
                }

                public String format(LogMessage message, Object... args) {
                    return MessageFormat.format(format(message), args);
                }

                public boolean isEnabledFor(Level level) {
                    return Level.FATAL.equals(level);
                }

                public void log(Level level, Throwable throwable) {
                    log(level, throwable, LogWorker.EXCEPTION_WITH_NO_MESSAGE);
                }

                public void log(Level level, LogMessage message) {
                    if (isEnabledFor(level)) {
                        System.err.println(format(message));
                    }
                }

                public void log(Level level, LogMessage message, Object... args) {
                    if (isEnabledFor(level)) {
                        System.err.println(format(message, args));
                    }
                }

                public void log(Level level, LogMessage message, Object arg1) {
                    if (isEnabledFor(level)) {
                        System.err.println(format(message, arg1));
                    }
                }

                public void log(Level level, Throwable throwable, LogMessage message) {
                    if (isEnabledFor(level)) {
                        System.err.println(format(message));
                        throwable.printStackTrace(System.err);
                    }
                }

                public void log(Level level, Throwable throwable, LogMessage message, Object... args) {
                    if (isEnabledFor(level)) {
                        System.err.println(format(message, args));
                        throwable.printStackTrace(System.err);
                    }
                }

                public void log(Level level, Throwable throwable, LogMessage message, Object arg1) {
                    if (isEnabledFor(level)) {
                        System.err.println(format(message, arg1));
                        throwable.printStackTrace(System.err);
                    }
                }
            }){};
        }
    }

Note: A production implementation would keep a single Logger instance for each source class rather than creating a new instance for each call to getLogger(java.lang.Class). It may be advisable to use java.lang.ref.WeakReference to hold on to the Logger instances in order to reduce "PermGen" memory leaks when re-deploying an application using your ACPL provider.

The jar file for this implementation would consists of:

    com/avaya/conferencing/logging/example/ExampleLoggerManager.class
    META-INF/services/com.avaya.conferencing.logging.LoggerManager
    META-INF/MANIFEST.MF

And the contents of META-INF/services/com.avaya.conferencing.logging.LoggerManager would be:

    #
    # Copyright 2008-2009 Avaya Inc.
    #
    # Licensed under the Apache License, Version 2.0 (the "License");
    # you may not use this file except in compliance with the License.
    # You may obtain a copy of the License at
    #     http://www.apache.org/licenses/LICENSE-2.0
    # Unless required by applicable law or agreed to in writing, software
    # distributed under the License is distributed on an "AS IS" BASIS,
    # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    # See the License for the specific language governing permissions and
    # limitations under the License.
    #
    #
    com.avaya.conferencing.logging.example.ExampleLoggerManager

Note: ACPL actually provides four loggers for each class to separate the different classes of log events:

The example provided does not separare the different classes of log events as it uses the Logger.Logger(com.avaya.conferencing.logging.LogWorker) constructor. If you need to separate the different classes of log events, you will need to use the Logger.Logger(com.avaya.conferencing.logging.LogWorker, com.avaya.conferencing.logging.LogWorker,com.avaya.conferencing.logging.LogWorker, com.avaya.conferencing.logging.LogWorker) constructor.


Avaya Conferencinge Plugable Logging API

Copyright © 2008-2009 Avaya, Inc. Licensed under the Apache License, Version 2.0.